/*
 * Intel Running Average Power Limit (RAPL) Driver
 * Copyright (c) 2013, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.
 *
 */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/log2.h>
#include <linux/bitmap.h>
#include <linux/delay.h>
#include <linux/sysfs.h>
#include <linux/cpu.h>
#include <linux/powercap.h>

#include <asm/processor.h>
#include <asm/cpu_device_id.h>

/* bitmasks for RAPL MSRs, used by primitive access functions */
#define ENERGY_STATUS_MASK      0xffffffff

#define POWER_LIMIT1_MASK       0x7FFF
#define POWER_LIMIT1_ENABLE     BIT(15)
#define POWER_LIMIT1_CLAMP      BIT(16)

#define POWER_LIMIT2_MASK       (0x7FFFULL<<32)
#define POWER_LIMIT2_ENABLE     BIT_ULL(47)
#define POWER_LIMIT2_CLAMP      BIT_ULL(48)
#define POWER_PACKAGE_LOCK      BIT_ULL(63)
#define POWER_PP_LOCK           BIT(31)

#define TIME_WINDOW1_MASK       (0x7FULL<<17)
#define TIME_WINDOW2_MASK       (0x7FULL<<49)

#define POWER_UNIT_OFFSET	0
#define POWER_UNIT_MASK		0x0F

#define ENERGY_UNIT_OFFSET	0x08
#define ENERGY_UNIT_MASK	0x1F00

#define TIME_UNIT_OFFSET	0x10
#define TIME_UNIT_MASK		0xF0000

#define POWER_INFO_MAX_MASK     (0x7fffULL<<32)
#define POWER_INFO_MIN_MASK     (0x7fffULL<<16)
#define POWER_INFO_MAX_TIME_WIN_MASK     (0x3fULL<<48)
#define POWER_INFO_THERMAL_SPEC_MASK     0x7fff

#define PERF_STATUS_THROTTLE_TIME_MASK 0xffffffff
#define PP_POLICY_MASK         0x1F

/* Non HW constants */
#define RAPL_PRIMITIVE_DERIVED       BIT(1) /* not from raw data */
#define RAPL_PRIMITIVE_DUMMY         BIT(2)

/* scale RAPL units to avoid floating point math inside kernel */
#define POWER_UNIT_SCALE     (1000000)
#define ENERGY_UNIT_SCALE    (1000000)
#define TIME_UNIT_SCALE      (1000000)

#define TIME_WINDOW_MAX_MSEC 40000
#define TIME_WINDOW_MIN_MSEC 250

enum unit_type {
	ARBITRARY_UNIT, /* no translation */
	POWER_UNIT,
	ENERGY_UNIT,
	TIME_UNIT,
};

enum rapl_domain_type {
	RAPL_DOMAIN_PACKAGE, /* entire package/socket */
	RAPL_DOMAIN_PP0, /* core power plane */
	RAPL_DOMAIN_PP1, /* graphics uncore */
	RAPL_DOMAIN_DRAM,/* DRAM control_type */
	RAPL_DOMAIN_MAX,
};

enum rapl_domain_msr_id {
	RAPL_DOMAIN_MSR_LIMIT,
	RAPL_DOMAIN_MSR_STATUS,
	RAPL_DOMAIN_MSR_PERF,
	RAPL_DOMAIN_MSR_POLICY,
	RAPL_DOMAIN_MSR_INFO,
	RAPL_DOMAIN_MSR_MAX,
};

/* per domain data, some are optional */
enum rapl_primitives {
	ENERGY_COUNTER,
	POWER_LIMIT1,
	POWER_LIMIT2,
	FW_LOCK,

	PL1_ENABLE,  /* power limit 1, aka long term */
	PL1_CLAMP,   /* allow frequency to go below OS request */
	PL2_ENABLE,  /* power limit 2, aka short term, instantaneous */
	PL2_CLAMP,

	TIME_WINDOW1, /* long term */
	TIME_WINDOW2, /* short term */
	THERMAL_SPEC_POWER,
	MAX_POWER,

	MIN_POWER,
	MAX_TIME_WINDOW,
	THROTTLED_TIME,
	PRIORITY_LEVEL,

	/* below are not raw primitive data */
	AVERAGE_POWER,
	NR_RAPL_PRIMITIVES,
};

#define NR_RAW_PRIMITIVES (NR_RAPL_PRIMITIVES - 2)

/* Can be expanded to include events, etc.*/
struct rapl_domain_data {
	u64 primitives[NR_RAPL_PRIMITIVES];
	unsigned long timestamp;
};


#define	DOMAIN_STATE_INACTIVE           BIT(0)
#define	DOMAIN_STATE_POWER_LIMIT_SET    BIT(1)
#define DOMAIN_STATE_BIOS_LOCKED        BIT(2)

#define NR_POWER_LIMITS (2)
struct rapl_power_limit {
	struct powercap_zone_constraint *constraint;
	int prim_id; /* primitive ID used to enable */
	struct rapl_domain *domain;
	const char *name;
};

static const char pl1_name[] = "long_term";
static const char pl2_name[] = "short_term";

struct rapl_domain {
	const char *name;
	enum rapl_domain_type id;
	int msrs[RAPL_DOMAIN_MSR_MAX];
	struct powercap_zone power_zone;
	struct rapl_domain_data rdd;
	struct rapl_power_limit rpl[NR_POWER_LIMITS];
	u64 attr_map; /* track capabilities */
	unsigned int state;
	int package_id;
};
#define power_zone_to_rapl_domain(_zone) \
	container_of(_zone, struct rapl_domain, power_zone)


/* Each physical package contains multiple domains, these are the common
 * data across RAPL domains within a package.
 */
struct rapl_package {
	unsigned int id; /* physical package/socket id */
	unsigned int nr_domains;
	unsigned long domain_map; /* bit map of active domains */
	unsigned int power_unit_divisor;
	unsigned int energy_unit_divisor;
	unsigned int time_unit_divisor;
	struct rapl_domain *domains; /* array of domains, sized at runtime */
	struct powercap_zone *power_zone; /* keep track of parent zone */
	int nr_cpus; /* active cpus on the package, topology info is lost during
		      * cpu hotplug. so we have to track ourselves.
		      */
	unsigned long power_limit_irq; /* keep track of package power limit
					* notify interrupt enable status.
					*/
	struct list_head plist;
};
#define PACKAGE_PLN_INT_SAVED   BIT(0)
#define MAX_PRIM_NAME (32)

/* per domain data. used to describe individual knobs such that access function
 * can be consolidated into one instead of many inline functions.
 */
struct rapl_primitive_info {
	const char *name;
	u64 mask;
	int shift;
	enum rapl_domain_msr_id id;
	enum unit_type unit;
	u32 flag;
};

#define PRIMITIVE_INFO_INIT(p, m, s, i, u, f) {	\
		.name = #p,			\
		.mask = m,			\
		.shift = s,			\
		.id = i,			\
		.unit = u,			\
		.flag = f			\
	}

static void rapl_init_domains(struct rapl_package *rp);
static int rapl_read_data_raw(struct rapl_domain *rd,
			enum rapl_primitives prim,
			bool xlate, u64 *data);
static int rapl_write_data_raw(struct rapl_domain *rd,
			enum rapl_primitives prim,
			unsigned long long value);
static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value,
			int to_raw);
static void package_power_limit_irq_save(int package_id);

static LIST_HEAD(rapl_packages); /* guarded by CPU hotplug lock */

static const char * const rapl_domain_names[] = {
	"package",
	"core",
	"uncore",
	"dram",
};

static struct powercap_control_type *control_type; /* PowerCap Controller */

/* caller to ensure CPU hotplug lock is held */
static struct rapl_package *find_package_by_id(int id)
{
	struct rapl_package *rp;

	list_for_each_entry(rp, &rapl_packages, plist) {
		if (rp->id == id)
			return rp;
	}

	return NULL;
}

/* caller to ensure CPU hotplug lock is held */
static int find_active_cpu_on_package(int package_id)
{
	int i;

	for_each_online_cpu(i) {
		if (topology_physical_package_id(i) == package_id)
			return i;
	}
	/* all CPUs on this package are offline */

	return -ENODEV;
}

/* caller must hold cpu hotplug lock */
static void rapl_cleanup_data(void)
{
	struct rapl_package *p, *tmp;

	list_for_each_entry_safe(p, tmp, &rapl_packages, plist) {
		kfree(p->domains);
		list_del(&p->plist);
		kfree(p);
	}
}

static int get_energy_counter(struct powercap_zone *power_zone, u64 *energy_raw)
{
	struct rapl_domain *rd;
	u64 energy_now;

	/* prevent CPU hotplug, make sure the RAPL domain does not go
	 * away while reading the counter.
	 */
	get_online_cpus();
	rd = power_zone_to_rapl_domain(power_zone);

	if (!rapl_read_data_raw(rd, ENERGY_COUNTER, true, &energy_now)) {
		*energy_raw = energy_now;
		put_online_cpus();

		return 0;
	}
	put_online_cpus();

	return -EIO;
}

static int get_max_energy_counter(struct powercap_zone *pcd_dev, u64 *energy)
{
	*energy = rapl_unit_xlate(0, ENERGY_UNIT, ENERGY_STATUS_MASK, 0);
	return 0;
}

static int release_zone(struct powercap_zone *power_zone)
{
	struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone);
	struct rapl_package *rp;

	/* package zone is the last zone of a package, we can free
	 * memory here since all children has been unregistered.
	 */
	if (rd->id == RAPL_DOMAIN_PACKAGE) {
		rp = find_package_by_id(rd->package_id);
		if (!rp) {
			dev_warn(&power_zone->dev, "no package id %s\n",
				rd->name);
			return -ENODEV;
		}
		kfree(rd);
		rp->domains = NULL;
	}

	return 0;

}

static int find_nr_power_limit(struct rapl_domain *rd)
{
	int i;

	for (i = 0; i < NR_POWER_LIMITS; i++) {
		if (rd->rpl[i].name == NULL)
			break;
	}

	return i;
}

static int set_domain_enable(struct powercap_zone *power_zone, bool mode)
{
	struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone);
	int nr_powerlimit;

	if (rd->state & DOMAIN_STATE_BIOS_LOCKED)
		return -EACCES;
	get_online_cpus();
	nr_powerlimit = find_nr_power_limit(rd);
	/* here we activate/deactivate the hardware for power limiting */
	rapl_write_data_raw(rd, PL1_ENABLE, mode);
	/* always enable clamp such that p-state can go below OS requested
	 * range. power capping priority over guranteed frequency.
	 */
	rapl_write_data_raw(rd, PL1_CLAMP, mode);
	/* some domains have pl2 */
	if (nr_powerlimit > 1) {
		rapl_write_data_raw(rd, PL2_ENABLE, mode);
		rapl_write_data_raw(rd, PL2_CLAMP, mode);
	}
	put_online_cpus();

	return 0;
}

static int get_domain_enable(struct powercap_zone *power_zone, bool *mode)
{
	struct rapl_domain *rd = power_zone_to_rapl_domain(power_zone);
	u64 val;

	if (rd->state & DOMAIN_STATE_BIOS_LOCKED) {
		*mode = false;
		return 0;
	}
	get_online_cpus();
	if (rapl_read_data_raw(rd, PL1_ENABLE, true, &val)) {
		put_online_cpus();
		return -EIO;
	}
	*mode = val;
	put_online_cpus();

	return 0;
}

/* per RAPL domain ops, in the order of rapl_domain_type */
static struct powercap_zone_ops zone_ops[] = {
	/* RAPL_DOMAIN_PACKAGE */
	{
		.get_energy_uj = get_energy_counter,
		.get_max_energy_range_uj = get_max_energy_counter,
		.release = release_zone,
		.set_enable = set_domain_enable,
		.get_enable = get_domain_enable,
	},
	/* RAPL_DOMAIN_PP0 */
	{
		.get_energy_uj = get_energy_counter,
		.get_max_energy_range_uj = get_max_energy_counter,
		.release = release_zone,
		.set_enable = set_domain_enable,
		.get_enable = get_domain_enable,
	},
	/* RAPL_DOMAIN_PP1 */
	{
		.get_energy_uj = get_energy_counter,
		.get_max_energy_range_uj = get_max_energy_counter,
		.release = release_zone,
		.set_enable = set_domain_enable,
		.get_enable = get_domain_enable,
	},
	/* RAPL_DOMAIN_DRAM */
	{
		.get_energy_uj = get_energy_counter,
		.get_max_energy_range_uj = get_max_energy_counter,
		.release = release_zone,
		.set_enable = set_domain_enable,
		.get_enable = get_domain_enable,
	},
};

static int set_power_limit(struct powercap_zone *power_zone, int id,
			u64 power_limit)
{
	struct rapl_domain *rd;
	struct rapl_package *rp;
	int ret = 0;

	get_online_cpus();
	rd = power_zone_to_rapl_domain(power_zone);
	rp = find_package_by_id(rd->package_id);
	if (!rp) {
		ret = -ENODEV;
		goto set_exit;
	}

	if (rd->state & DOMAIN_STATE_BIOS_LOCKED) {
		dev_warn(&power_zone->dev, "%s locked by BIOS, monitoring only\n",
			rd->name);
		ret = -EACCES;
		goto set_exit;
	}

	switch (rd->rpl[id].prim_id) {
	case PL1_ENABLE:
		rapl_write_data_raw(rd, POWER_LIMIT1, power_limit);
		break;
	case PL2_ENABLE:
		rapl_write_data_raw(rd, POWER_LIMIT2, power_limit);
		break;
	default:
		ret = -EINVAL;
	}
	if (!ret)
		package_power_limit_irq_save(rd->package_id);
set_exit:
	put_online_cpus();
	return ret;
}

static int get_current_power_limit(struct powercap_zone *power_zone, int id,
					u64 *data)
{
	struct rapl_domain *rd;
	u64 val;
	int prim;
	int ret = 0;

	get_online_cpus();
	rd = power_zone_to_rapl_domain(power_zone);
	switch (rd->rpl[id].prim_id) {
	case PL1_ENABLE:
		prim = POWER_LIMIT1;
		break;
	case PL2_ENABLE:
		prim = POWER_LIMIT2;
		break;
	default:
		put_online_cpus();
		return -EINVAL;
	}
	if (rapl_read_data_raw(rd, prim, true, &val))
		ret = -EIO;
	else
		*data = val;

	put_online_cpus();

	return ret;
}

static int set_time_window(struct powercap_zone *power_zone, int id,
								u64 window)
{
	struct rapl_domain *rd;
	int ret = 0;

	get_online_cpus();
	rd = power_zone_to_rapl_domain(power_zone);
	switch (rd->rpl[id].prim_id) {
	case PL1_ENABLE:
		rapl_write_data_raw(rd, TIME_WINDOW1, window);
		break;
	case PL2_ENABLE:
		rapl_write_data_raw(rd, TIME_WINDOW2, window);
		break;
	default:
		ret = -EINVAL;
	}
	put_online_cpus();
	return ret;
}

static int get_time_window(struct powercap_zone *power_zone, int id, u64 *data)
{
	struct rapl_domain *rd;
	u64 val;
	int ret = 0;

	get_online_cpus();
	rd = power_zone_to_rapl_domain(power_zone);
	switch (rd->rpl[id].prim_id) {
	case PL1_ENABLE:
		ret = rapl_read_data_raw(rd, TIME_WINDOW1, true, &val);
		break;
	case PL2_ENABLE:
		ret = rapl_read_data_raw(rd, TIME_WINDOW2, true, &val);
		break;
	default:
		put_online_cpus();
		return -EINVAL;
	}
	if (!ret)
		*data = val;
	put_online_cpus();

	return ret;
}

static const char *get_constraint_name(struct powercap_zone *power_zone, int id)
{
	struct rapl_power_limit *rpl;
	struct rapl_domain *rd;

	rd = power_zone_to_rapl_domain(power_zone);
	rpl = (struct rapl_power_limit *) &rd->rpl[id];

	return rpl->name;
}


static int get_max_power(struct powercap_zone *power_zone, int id,
					u64 *data)
{
	struct rapl_domain *rd;
	u64 val;
	int prim;
	int ret = 0;

	get_online_cpus();
	rd = power_zone_to_rapl_domain(power_zone);
	switch (rd->rpl[id].prim_id) {
	case PL1_ENABLE:
		prim = THERMAL_SPEC_POWER;
		break;
	case PL2_ENABLE:
		prim = MAX_POWER;
		break;
	default:
		put_online_cpus();
		return -EINVAL;
	}
	if (rapl_read_data_raw(rd, prim, true, &val))
		ret = -EIO;
	else
		*data = val;

	put_online_cpus();

	return ret;
}

static struct powercap_zone_constraint_ops constraint_ops = {
	.set_power_limit_uw = set_power_limit,
	.get_power_limit_uw = get_current_power_limit,
	.set_time_window_us = set_time_window,
	.get_time_window_us = get_time_window,
	.get_max_power_uw = get_max_power,
	.get_name = get_constraint_name,
};

/* called after domain detection and package level data are set */
static void rapl_init_domains(struct rapl_package *rp)
{
	int i;
	struct rapl_domain *rd = rp->domains;

	for (i = 0; i < RAPL_DOMAIN_MAX; i++) {
		unsigned int mask = rp->domain_map & (1 << i);
		switch (mask) {
		case BIT(RAPL_DOMAIN_PACKAGE):
			rd->name = rapl_domain_names[RAPL_DOMAIN_PACKAGE];
			rd->id = RAPL_DOMAIN_PACKAGE;
			rd->msrs[0] = MSR_PKG_POWER_LIMIT;
			rd->msrs[1] = MSR_PKG_ENERGY_STATUS;
			rd->msrs[2] = MSR_PKG_PERF_STATUS;
			rd->msrs[3] = 0;
			rd->msrs[4] = MSR_PKG_POWER_INFO;
			rd->rpl[0].prim_id = PL1_ENABLE;
			rd->rpl[0].name = pl1_name;
			rd->rpl[1].prim_id = PL2_ENABLE;
			rd->rpl[1].name = pl2_name;
			break;
		case BIT(RAPL_DOMAIN_PP0):
			rd->name = rapl_domain_names[RAPL_DOMAIN_PP0];
			rd->id = RAPL_DOMAIN_PP0;
			rd->msrs[0] = MSR_PP0_POWER_LIMIT;
			rd->msrs[1] = MSR_PP0_ENERGY_STATUS;
			rd->msrs[2] = 0;
			rd->msrs[3] = MSR_PP0_POLICY;
			rd->msrs[4] = 0;
			rd->rpl[0].prim_id = PL1_ENABLE;
			rd->rpl[0].name = pl1_name;
			break;
		case BIT(RAPL_DOMAIN_PP1):
			rd->name = rapl_domain_names[RAPL_DOMAIN_PP1];
			rd->id = RAPL_DOMAIN_PP1;
			rd->msrs[0] = MSR_PP1_POWER_LIMIT;
			rd->msrs[1] = MSR_PP1_ENERGY_STATUS;
			rd->msrs[2] = 0;
			rd->msrs[3] = MSR_PP1_POLICY;
			rd->msrs[4] = 0;
			rd->rpl[0].prim_id = PL1_ENABLE;
			rd->rpl[0].name = pl1_name;
			break;
		case BIT(RAPL_DOMAIN_DRAM):
			rd->name = rapl_domain_names[RAPL_DOMAIN_DRAM];
			rd->id = RAPL_DOMAIN_DRAM;
			rd->msrs[0] = MSR_DRAM_POWER_LIMIT;
			rd->msrs[1] = MSR_DRAM_ENERGY_STATUS;
			rd->msrs[2] = MSR_DRAM_PERF_STATUS;
			rd->msrs[3] = 0;
			rd->msrs[4] = MSR_DRAM_POWER_INFO;
			rd->rpl[0].prim_id = PL1_ENABLE;
			rd->rpl[0].name = pl1_name;
			break;
		}
		if (mask) {
			rd->package_id = rp->id;
			rd++;
		}
	}
}

static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value,
			int to_raw)
{
	u64 divisor = 1;
	int scale = 1; /* scale to user friendly data without floating point */
	u64 f, y; /* fraction and exp. used for time unit */
	struct rapl_package *rp;

	rp = find_package_by_id(package);
	if (!rp)
		return value;

	switch (type) {
	case POWER_UNIT:
		divisor = rp->power_unit_divisor;
		scale = POWER_UNIT_SCALE;
		break;
	case ENERGY_UNIT:
		scale = ENERGY_UNIT_SCALE;
		divisor = rp->energy_unit_divisor;
		break;
	case TIME_UNIT:
		divisor = rp->time_unit_divisor;
		scale = TIME_UNIT_SCALE;
		/* special processing based on 2^Y*(1+F)/4 = val/divisor, refer
		 * to Intel Software Developer's manual Vol. 3a, CH 14.7.4.
		 */
		if (!to_raw) {
			f = (value & 0x60) >> 5;
			y = value & 0x1f;
			value = (1 << y) * (4 + f) * scale / 4;
			return div64_u64(value, divisor);
		} else {
			do_div(value, scale);
			value *= divisor;
			y = ilog2(value);
			f = div64_u64(4 * (value - (1 << y)), 1 << y);
			value = (y & 0x1f) | ((f & 0x3) << 5);
			return value;
		}
		break;
	case ARBITRARY_UNIT:
	default:
		return value;
	};

	if (to_raw)
		return div64_u64(value * divisor, scale);
	else
		return div64_u64(value * scale, divisor);
}

/* in the order of enum rapl_primitives */
static struct rapl_primitive_info rpi[] = {
	/* name, mask, shift, msr index, unit divisor */
	PRIMITIVE_INFO_INIT(ENERGY_COUNTER, ENERGY_STATUS_MASK, 0,
				RAPL_DOMAIN_MSR_STATUS, ENERGY_UNIT, 0),
	PRIMITIVE_INFO_INIT(POWER_LIMIT1, POWER_LIMIT1_MASK, 0,
				RAPL_DOMAIN_MSR_LIMIT, POWER_UNIT, 0),
	PRIMITIVE_INFO_INIT(POWER_LIMIT2, POWER_LIMIT2_MASK, 32,
				RAPL_DOMAIN_MSR_LIMIT, POWER_UNIT, 0),
	PRIMITIVE_INFO_INIT(FW_LOCK, POWER_PP_LOCK, 31,
				RAPL_DOMAIN_MSR_LIMIT, ARBITRARY_UNIT, 0),
	PRIMITIVE_INFO_INIT(PL1_ENABLE, POWER_LIMIT1_ENABLE, 15,
				RAPL_DOMAIN_MSR_LIMIT, ARBITRARY_UNIT, 0),
	PRIMITIVE_INFO_INIT(PL1_CLAMP, POWER_LIMIT1_CLAMP, 16,
				RAPL_DOMAIN_MSR_LIMIT, ARBITRARY_UNIT, 0),
	PRIMITIVE_INFO_INIT(PL2_ENABLE, POWER_LIMIT2_ENABLE, 47,
				RAPL_DOMAIN_MSR_LIMIT, ARBITRARY_UNIT, 0),
	PRIMITIVE_INFO_INIT(PL2_CLAMP, POWER_LIMIT2_CLAMP, 48,
				RAPL_DOMAIN_MSR_LIMIT, ARBITRARY_UNIT, 0),
	PRIMITIVE_INFO_INIT(TIME_WINDOW1, TIME_WINDOW1_MASK, 17,
				RAPL_DOMAIN_MSR_LIMIT, TIME_UNIT, 0),
	PRIMITIVE_INFO_INIT(TIME_WINDOW2, TIME_WINDOW2_MASK, 49,
				RAPL_DOMAIN_MSR_LIMIT, TIME_UNIT, 0),
	PRIMITIVE_INFO_INIT(THERMAL_SPEC_POWER, POWER_INFO_THERMAL_SPEC_MASK,
				0, RAPL_DOMAIN_MSR_INFO, POWER_UNIT, 0),
	PRIMITIVE_INFO_INIT(MAX_POWER, POWER_INFO_MAX_MASK, 32,
				RAPL_DOMAIN_MSR_INFO, POWER_UNIT, 0),
	PRIMITIVE_INFO_INIT(MIN_POWER, POWER_INFO_MIN_MASK, 16,
				RAPL_DOMAIN_MSR_INFO, POWER_UNIT, 0),
	PRIMITIVE_INFO_INIT(MAX_TIME_WINDOW, POWER_INFO_MAX_TIME_WIN_MASK, 48,
				RAPL_DOMAIN_MSR_INFO, TIME_UNIT, 0),
	PRIMITIVE_INFO_INIT(THROTTLED_TIME, PERF_STATUS_THROTTLE_TIME_MASK, 0,
				RAPL_DOMAIN_MSR_PERF, TIME_UNIT, 0),
	PRIMITIVE_INFO_INIT(PRIORITY_LEVEL, PP_POLICY_MASK, 0,
				RAPL_DOMAIN_MSR_POLICY, ARBITRARY_UNIT, 0),
	/* non-hardware */
	PRIMITIVE_INFO_INIT(AVERAGE_POWER, 0, 0, 0, POWER_UNIT,
				RAPL_PRIMITIVE_DERIVED),
	{NULL, 0, 0, 0},
};

/* Read primitive data based on its related struct rapl_primitive_info.
 * if xlate flag is set, return translated data based on data units, i.e.
 * time, energy, and power.
 * RAPL MSRs are non-architectual and are laid out not consistently across
 * domains. Here we use primitive info to allow writing consolidated access
 * functions.
 * For a given primitive, it is processed by MSR mask and shift. Unit conversion
 * is pre-assigned based on RAPL unit MSRs read at init time.
 * 63-------------------------- 31--------------------------- 0
 * |                           xxxxx (mask)                   |
 * |                                |<- shift ----------------|
 * 63-------------------------- 31--------------------------- 0
 */
static int rapl_read_data_raw(struct rapl_domain *rd,
			enum rapl_primitives prim,
			bool xlate, u64 *data)
{
	u64 value, final;
	u32 msr;
	struct rapl_primitive_info *rp = &rpi[prim];
	int cpu;

	if (!rp->name || rp->flag & RAPL_PRIMITIVE_DUMMY)
		return -EINVAL;

	msr = rd->msrs[rp->id];
	if (!msr)
		return -EINVAL;
	/* use physical package id to look up active cpus */
	cpu = find_active_cpu_on_package(rd->package_id);
	if (cpu < 0)
		return cpu;

	/* special-case package domain, which uses a different bit*/
	if (prim == FW_LOCK && rd->id == RAPL_DOMAIN_PACKAGE) {
		rp->mask = POWER_PACKAGE_LOCK;
		rp->shift = 63;
	}
	/* non-hardware data are collected by the polling thread */
	if (rp->flag & RAPL_PRIMITIVE_DERIVED) {
		*data = rd->rdd.primitives[prim];
		return 0;
	}

	if (rdmsrl_safe_on_cpu(cpu, msr, &value)) {
		pr_debug("failed to read msr 0x%x on cpu %d\n", msr, cpu);
		return -EIO;
	}

	final = value & rp->mask;
	final = final >> rp->shift;
	if (xlate)
		*data = rapl_unit_xlate(rd->package_id, rp->unit, final, 0);
	else
		*data = final;

	return 0;
}

/* Similar use of primitive info in the read counterpart */
static int rapl_write_data_raw(struct rapl_domain *rd,
			enum rapl_primitives prim,
			unsigned long long value)
{
	u64 msr_val;
	u32 msr;
	struct rapl_primitive_info *rp = &rpi[prim];
	int cpu;

	cpu = find_active_cpu_on_package(rd->package_id);
	if (cpu < 0)
		return cpu;
	msr = rd->msrs[rp->id];
	if (rdmsrl_safe_on_cpu(cpu, msr, &msr_val)) {
		dev_dbg(&rd->power_zone.dev,
			"failed to read msr 0x%x on cpu %d\n", msr, cpu);
		return -EIO;
	}
	value = rapl_unit_xlate(rd->package_id, rp->unit, value, 1);
	msr_val &= ~rp->mask;
	msr_val |= value << rp->shift;
	if (wrmsrl_safe_on_cpu(cpu, msr, msr_val)) {
		dev_dbg(&rd->power_zone.dev,
			"failed to write msr 0x%x on cpu %d\n", msr, cpu);
		return -EIO;
	}

	return 0;
}

static const struct x86_cpu_id energy_unit_quirk_ids[] = {
	{ X86_VENDOR_INTEL, 6, 0x37},/* Valleyview */
	{}
};

static int rapl_check_unit(struct rapl_package *rp, int cpu)
{
	u64 msr_val;
	u32 value;

	if (rdmsrl_safe_on_cpu(cpu, MSR_RAPL_POWER_UNIT, &msr_val)) {
		pr_err("Failed to read power unit MSR 0x%x on CPU %d, exit.\n",
			MSR_RAPL_POWER_UNIT, cpu);
		return -ENODEV;
	}

	/* Raw RAPL data stored in MSRs are in certain scales. We need to
	 * convert them into standard units based on the divisors reported in
	 * the RAPL unit MSRs.
	 * i.e.
	 * energy unit: 1/enery_unit_divisor Joules
	 * power unit: 1/power_unit_divisor Watts
	 * time unit: 1/time_unit_divisor Seconds
	 */
	value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET;
	/* some CPUs have different way to calculate energy unit */
	if (x86_match_cpu(energy_unit_quirk_ids))
		rp->energy_unit_divisor = 1000000 / (1 << value);
	else
		rp->energy_unit_divisor = 1 << value;

	value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET;
	rp->power_unit_divisor = 1 << value;

	value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET;
	rp->time_unit_divisor = 1 << value;

	pr_debug("Physical package %d units: energy=%d, time=%d, power=%d\n",
		rp->id,
		rp->energy_unit_divisor,
		rp->time_unit_divisor,
		rp->power_unit_divisor);

	return 0;
}

/* REVISIT:
 * When package power limit is set artificially low by RAPL, LVT
 * thermal interrupt for package power limit should be ignored
 * since we are not really exceeding the real limit. The intention
 * is to avoid excessive interrupts while we are trying to save power.
 * A useful feature might be routing the package_power_limit interrupt
 * to userspace via eventfd. once we have a usecase, this is simple
 * to do by adding an atomic notifier.
 */

static void package_power_limit_irq_save(int package_id)
{
	u32 l, h = 0;
	int cpu;
	struct rapl_package *rp;

	rp = find_package_by_id(package_id);
	if (!rp)
		return;

	if (!boot_cpu_has(X86_FEATURE_PTS) || !boot_cpu_has(X86_FEATURE_PLN))
		return;

	cpu = find_active_cpu_on_package(package_id);
	if (cpu < 0)
		return;
	/* save the state of PLN irq mask bit before disabling it */
	rdmsr_safe_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &l, &h);
	if (!(rp->power_limit_irq & PACKAGE_PLN_INT_SAVED)) {
		rp->power_limit_irq = l & PACKAGE_THERM_INT_PLN_ENABLE;
		rp->power_limit_irq |= PACKAGE_PLN_INT_SAVED;
	}
	l &= ~PACKAGE_THERM_INT_PLN_ENABLE;
	wrmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
}

/* restore per package power limit interrupt enable state */
static void package_power_limit_irq_restore(int package_id)
{
	u32 l, h;
	int cpu;
	struct rapl_package *rp;

	rp = find_package_by_id(package_id);
	if (!rp)
		return;

	if (!boot_cpu_has(X86_FEATURE_PTS) || !boot_cpu_has(X86_FEATURE_PLN))
		return;

	cpu = find_active_cpu_on_package(package_id);
	if (cpu < 0)
		return;

	/* irq enable state not saved, nothing to restore */
	if (!(rp->power_limit_irq & PACKAGE_PLN_INT_SAVED))
		return;
	rdmsr_safe_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &l, &h);

	if (rp->power_limit_irq & PACKAGE_THERM_INT_PLN_ENABLE)
		l |= PACKAGE_THERM_INT_PLN_ENABLE;
	else
		l &= ~PACKAGE_THERM_INT_PLN_ENABLE;

	wrmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
}

static const struct x86_cpu_id rapl_ids[] = {
	{ X86_VENDOR_INTEL, 6, 0x2a},/* Sandy Bridge */
	{ X86_VENDOR_INTEL, 6, 0x2d},/* Sandy Bridge EP */
	{ X86_VENDOR_INTEL, 6, 0x37},/* Valleyview */
	{ X86_VENDOR_INTEL, 6, 0x3a},/* Ivy Bridge */
	{ X86_VENDOR_INTEL, 6, 0x45},/* Haswell */
	/* TODO: Add more CPU IDs after testing */
	{}
};
MODULE_DEVICE_TABLE(x86cpu, rapl_ids);

/* read once for all raw primitive data for all packages, domains */
static void rapl_update_domain_data(void)
{
	int dmn, prim;
	u64 val;
	struct rapl_package *rp;

	list_for_each_entry(rp, &rapl_packages, plist) {
		for (dmn = 0; dmn < rp->nr_domains; dmn++) {
			pr_debug("update package %d domain %s data\n", rp->id,
				rp->domains[dmn].name);
			/* exclude non-raw primitives */
			for (prim = 0; prim < NR_RAW_PRIMITIVES; prim++)
				if (!rapl_read_data_raw(&rp->domains[dmn], prim,
								rpi[prim].unit,
								&val))
					rp->domains[dmn].rdd.primitives[prim] =
									val;
		}
	}

}

static int rapl_unregister_powercap(void)
{
	struct rapl_package *rp;
	struct rapl_domain *rd, *rd_package = NULL;

	/* unregister all active rapl packages from the powercap layer,
	 * hotplug lock held
	 */
	list_for_each_entry(rp, &rapl_packages, plist) {
		package_power_limit_irq_restore(rp->id);

		for (rd = rp->domains; rd < rp->domains + rp->nr_domains;
		     rd++) {
			pr_debug("remove package, undo power limit on %d: %s\n",
				rp->id, rd->name);
			rapl_write_data_raw(rd, PL1_ENABLE, 0);
			rapl_write_data_raw(rd, PL2_ENABLE, 0);
			rapl_write_data_raw(rd, PL1_CLAMP, 0);
			rapl_write_data_raw(rd, PL2_CLAMP, 0);
			if (rd->id == RAPL_DOMAIN_PACKAGE) {
				rd_package = rd;
				continue;
			}
			powercap_unregister_zone(control_type, &rd->power_zone);
		}
		/* do the package zone last */
		if (rd_package)
			powercap_unregister_zone(control_type,
						&rd_package->power_zone);
	}
	powercap_unregister_control_type(control_type);

	return 0;
}

static int rapl_package_register_powercap(struct rapl_package *rp)
{
	struct rapl_domain *rd;
	int ret = 0;
	char dev_name[17]; /* max domain name = 7 + 1 + 8 for int + 1 for null*/
	struct powercap_zone *power_zone = NULL;
	int nr_pl;

	/* first we register package domain as the parent zone*/
	for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
		if (rd->id == RAPL_DOMAIN_PACKAGE) {
			nr_pl = find_nr_power_limit(rd);
			pr_debug("register socket %d package domain %s\n",
				rp->id, rd->name);
			memset(dev_name, 0, sizeof(dev_name));
			snprintf(dev_name, sizeof(dev_name), "%s-%d",
				rd->name, rp->id);
			power_zone = powercap_register_zone(&rd->power_zone,
							control_type,
							dev_name, NULL,
							&zone_ops[rd->id],
							nr_pl,
							&constraint_ops);
			if (IS_ERR(power_zone)) {
				pr_debug("failed to register package, %d\n",
					rp->id);
				ret = PTR_ERR(power_zone);
				goto exit_package;
			}
			/* track parent zone in per package/socket data */
			rp->power_zone = power_zone;
			/* done, only one package domain per socket */
			break;
		}
	}
	if (!power_zone) {
		pr_err("no package domain found, unknown topology!\n");
		ret = -ENODEV;
		goto exit_package;
	}
	/* now register domains as children of the socket/package*/
	for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
		if (rd->id == RAPL_DOMAIN_PACKAGE)
			continue;
		/* number of power limits per domain varies */
		nr_pl = find_nr_power_limit(rd);
		power_zone = powercap_register_zone(&rd->power_zone,
						control_type, rd->name,
						rp->power_zone,
						&zone_ops[rd->id], nr_pl,
						&constraint_ops);

		if (IS_ERR(power_zone)) {
			pr_debug("failed to register power_zone, %d:%s:%s\n",
				rp->id, rd->name, dev_name);
			ret = PTR_ERR(power_zone);
			goto err_cleanup;
		}
	}

exit_package:
	return ret;
err_cleanup:
	/* clean up previously initialized domains within the package if we
	 * failed after the first domain setup.
	 */
	while (--rd >= rp->domains) {
		pr_debug("unregister package %d domain %s\n", rp->id, rd->name);
		powercap_unregister_zone(control_type, &rd->power_zone);
	}

	return ret;
}

static int rapl_register_powercap(void)
{
	struct rapl_domain *rd;
	struct rapl_package *rp;
	int ret = 0;

	control_type = powercap_register_control_type(NULL, "intel-rapl", NULL);
	if (IS_ERR(control_type)) {
		pr_debug("failed to register powercap control_type.\n");
		return PTR_ERR(control_type);
	}
	/* read the initial data */
	rapl_update_domain_data();
	list_for_each_entry(rp, &rapl_packages, plist)
		if (rapl_package_register_powercap(rp))
			goto err_cleanup_package;
	return ret;

err_cleanup_package:
	/* clean up previously initialized packages */
	list_for_each_entry_continue_reverse(rp, &rapl_packages, plist) {
		for (rd = rp->domains; rd < rp->domains + rp->nr_domains;
		     rd++) {
			pr_debug("unregister zone/package %d, %s domain\n",
				rp->id, rd->name);
			powercap_unregister_zone(control_type, &rd->power_zone);
		}
	}

	return ret;
}

static int rapl_check_domain(int cpu, int domain)
{
	unsigned msr;
	u64 val1, val2 = 0;
	int retry = 0;

	switch (domain) {
	case RAPL_DOMAIN_PACKAGE:
		msr = MSR_PKG_ENERGY_STATUS;
		break;
	case RAPL_DOMAIN_PP0:
		msr = MSR_PP0_ENERGY_STATUS;
		break;
	case RAPL_DOMAIN_PP1:
		msr = MSR_PP1_ENERGY_STATUS;
		break;
	case RAPL_DOMAIN_DRAM:
		msr = MSR_DRAM_ENERGY_STATUS;
		break;
	default:
		pr_err("invalid domain id %d\n", domain);
		return -EINVAL;
	}
	if (rdmsrl_safe_on_cpu(cpu, msr, &val1))
		return -ENODEV;

	/* PP1/uncore/graphics domain may not be active at the time of
	 * driver loading. So skip further checks.
	 */
	if (domain == RAPL_DOMAIN_PP1)
		return 0;
	/* energy counters roll slowly on some domains */
	while (++retry < 10) {
		usleep_range(10000, 15000);
		rdmsrl_safe_on_cpu(cpu, msr, &val2);
		if ((val1 & ENERGY_STATUS_MASK) != (val2 & ENERGY_STATUS_MASK))
			return 0;
	}
	/* if energy counter does not change, report as bad domain */
	pr_info("domain %s energy ctr %llu:%llu not working, skip\n",
		rapl_domain_names[domain], val1, val2);

	return -ENODEV;
}

/* Detect active and valid domains for the given CPU, caller must
 * ensure the CPU belongs to the targeted package and CPU hotlug is disabled.
 */
static int rapl_detect_domains(struct rapl_package *rp, int cpu)
{
	int i;
	int ret = 0;
	struct rapl_domain *rd;
	u64 locked;

	for (i = 0; i < RAPL_DOMAIN_MAX; i++) {
		/* use physical package id to read counters */
		if (!rapl_check_domain(cpu, i))
			rp->domain_map |= 1 << i;
	}
	rp->nr_domains = bitmap_weight(&rp->domain_map,	RAPL_DOMAIN_MAX);
	if (!rp->nr_domains) {
		pr_err("no valid rapl domains found in package %d\n", rp->id);
		ret = -ENODEV;
		goto done;
	}
	pr_debug("found %d domains on package %d\n", rp->nr_domains, rp->id);

	rp->domains = kcalloc(rp->nr_domains + 1, sizeof(struct rapl_domain),
			GFP_KERNEL);
	if (!rp->domains) {
		ret = -ENOMEM;
		goto done;
	}
	rapl_init_domains(rp);

	for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
		/* check if the domain is locked by BIOS */
		if (rapl_read_data_raw(rd, FW_LOCK, false, &locked)) {
			pr_info("RAPL package %d domain %s locked by BIOS\n",
				rp->id, rd->name);
				rd->state |= DOMAIN_STATE_BIOS_LOCKED;
		}
	}


done:
	return ret;
}

static bool is_package_new(int package)
{
	struct rapl_package *rp;

	/* caller prevents cpu hotplug, there will be no new packages added
	 * or deleted while traversing the package list, no need for locking.
	 */
	list_for_each_entry(rp, &rapl_packages, plist)
		if (package == rp->id)
			return false;

	return true;
}

/* RAPL interface can be made of a two-level hierarchy: package level and domain
 * level. We first detect the number of packages then domains of each package.
 * We have to consider the possiblity of CPU online/offline due to hotplug and
 * other scenarios.
 */
static int rapl_detect_topology(void)
{
	int i;
	int phy_package_id;
	struct rapl_package *new_package, *rp;

	for_each_online_cpu(i) {
		phy_package_id = topology_physical_package_id(i);
		if (is_package_new(phy_package_id)) {
			new_package = kzalloc(sizeof(*rp), GFP_KERNEL);
			if (!new_package) {
				rapl_cleanup_data();
				return -ENOMEM;
			}
			/* add the new package to the list */
			new_package->id = phy_package_id;
			new_package->nr_cpus = 1;

			/* check if the package contains valid domains */
			if (rapl_detect_domains(new_package, i) ||
				rapl_check_unit(new_package, i)) {
				kfree(new_package->domains);
				kfree(new_package);
				/* free up the packages already initialized */
				rapl_cleanup_data();
				return -ENODEV;
			}
			INIT_LIST_HEAD(&new_package->plist);
			list_add(&new_package->plist, &rapl_packages);
		} else {
			rp = find_package_by_id(phy_package_id);
			if (rp)
				++rp->nr_cpus;
		}
	}

	return 0;
}

/* called from CPU hotplug notifier, hotplug lock held */
static void rapl_remove_package(struct rapl_package *rp)
{
	struct rapl_domain *rd, *rd_package = NULL;

	for (rd = rp->domains; rd < rp->domains + rp->nr_domains; rd++) {
		if (rd->id == RAPL_DOMAIN_PACKAGE) {
			rd_package = rd;
			continue;
		}
		pr_debug("remove package %d, %s domain\n", rp->id, rd->name);
		powercap_unregister_zone(control_type, &rd->power_zone);
	}
	/* do parent zone last */
	powercap_unregister_zone(control_type, &rd_package->power_zone);
	list_del(&rp->plist);
	kfree(rp);
}

/* called from CPU hotplug notifier, hotplug lock held */
static int rapl_add_package(int cpu)
{
	int ret = 0;
	int phy_package_id;
	struct rapl_package *rp;

	phy_package_id = topology_physical_package_id(cpu);
	rp = kzalloc(sizeof(struct rapl_package), GFP_KERNEL);
	if (!rp)
		return -ENOMEM;

	/* add the new package to the list */
	rp->id = phy_package_id;
	rp->nr_cpus = 1;
	/* check if the package contains valid domains */
	if (rapl_detect_domains(rp, cpu) ||
		rapl_check_unit(rp, cpu)) {
		ret = -ENODEV;
		goto err_free_package;
	}
	if (!rapl_package_register_powercap(rp)) {
		INIT_LIST_HEAD(&rp->plist);
		list_add(&rp->plist, &rapl_packages);
		return ret;
	}

err_free_package:
	kfree(rp->domains);
	kfree(rp);

	return ret;
}

/* Handles CPU hotplug on multi-socket systems.
 * If a CPU goes online as the first CPU of the physical package
 * we add the RAPL package to the system. Similarly, when the last
 * CPU of the package is removed, we remove the RAPL package and its
 * associated domains. Cooling devices are handled accordingly at
 * per-domain level.
 */
static int rapl_cpu_callback(struct notifier_block *nfb,
				unsigned long action, void *hcpu)
{
	unsigned long cpu = (unsigned long)hcpu;
	int phy_package_id;
	struct rapl_package *rp;

	phy_package_id = topology_physical_package_id(cpu);
	switch (action) {
	case CPU_ONLINE:
	case CPU_ONLINE_FROZEN:
	case CPU_DOWN_FAILED:
	case CPU_DOWN_FAILED_FROZEN:
		rp = find_package_by_id(phy_package_id);
		if (rp)
			++rp->nr_cpus;
		else
			rapl_add_package(cpu);
		break;
	case CPU_DOWN_PREPARE:
	case CPU_DOWN_PREPARE_FROZEN:
		rp = find_package_by_id(phy_package_id);
		if (!rp)
			break;
		if (--rp->nr_cpus == 0)
			rapl_remove_package(rp);
	}

	return NOTIFY_OK;
}

static struct notifier_block rapl_cpu_notifier = {
	.notifier_call = rapl_cpu_callback,
};

static int __init rapl_init(void)
{
	int ret = 0;

	if (!x86_match_cpu(rapl_ids)) {
		pr_err("driver does not support CPU family %d model %d\n",
			boot_cpu_data.x86, boot_cpu_data.x86_model);

		return -ENODEV;
	}

	cpu_notifier_register_begin();

	/* prevent CPU hotplug during detection */
	get_online_cpus();
	ret = rapl_detect_topology();
	if (ret)
		goto done;

	if (rapl_register_powercap()) {
		rapl_cleanup_data();
		ret = -ENODEV;
		goto done;
	}
	__register_hotcpu_notifier(&rapl_cpu_notifier);
done:
	put_online_cpus();
	cpu_notifier_register_done();

	return ret;
}

static void __exit rapl_exit(void)
{
	cpu_notifier_register_begin();
	get_online_cpus();
	__unregister_hotcpu_notifier(&rapl_cpu_notifier);
	rapl_unregister_powercap();
	rapl_cleanup_data();
	put_online_cpus();
	cpu_notifier_register_done();
}

module_init(rapl_init);
module_exit(rapl_exit);

MODULE_DESCRIPTION("Driver for Intel RAPL (Running Average Power Limit)");
MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@intel.com>");
MODULE_LICENSE("GPL v2");
