// SPDX-License-Identifier: GPL-2.0-only
/*
 * L220/L310 cache controller support
 *
 * Copyright (C) 2016 ARM Limited
 */
#include <linux/errno.h>
#include <linux/hrtimer.h>
#include <linux/io.h>
#include <linux/list.h>
#include <linux/perf_event.h>
#include <linux/printk.h>
#include <linux/slab.h>
#include <linux/types.h>

#include <asm/hardware/cache-l2x0.h>

#define PMU_NR_COUNTERS 2

static void __iomem *l2x0_base;
static struct pmu *l2x0_pmu;
static cpumask_t pmu_cpu;

static const char *l2x0_name;

static ktime_t l2x0_pmu_poll_period;
static struct hrtimer l2x0_pmu_hrtimer;

/*
 * The L220/PL310 PMU has two equivalent counters, Counter1 and Counter0.
 * Registers controlling these are laid out in pairs, in descending order, i.e.
 * the register for Counter1 comes first, followed by the register for
 * Counter0.
 * We ensure that idx 0 -> Counter0, and idx1 -> Counter1.
 */
static struct perf_event *events[PMU_NR_COUNTERS];

/* Find an unused counter */
static int l2x0_pmu_find_idx(void)
{
	int i;

	for (i = 0; i < PMU_NR_COUNTERS; i++) {
		if (!events[i])
			return i;
	}

	return -1;
}

/* How many counters are allocated? */
static int l2x0_pmu_num_active_counters(void)
{
	int i, cnt = 0;

	for (i = 0; i < PMU_NR_COUNTERS; i++) {
		if (events[i])
			cnt++;
	}

	return cnt;
}

static void l2x0_pmu_counter_config_write(int idx, u32 val)
{
	writel_relaxed(val, l2x0_base + L2X0_EVENT_CNT0_CFG - 4 * idx);
}

static u32 l2x0_pmu_counter_read(int idx)
{
	return readl_relaxed(l2x0_base + L2X0_EVENT_CNT0_VAL - 4 * idx);
}

static void l2x0_pmu_counter_write(int idx, u32 val)
{
	writel_relaxed(val, l2x0_base + L2X0_EVENT_CNT0_VAL - 4 * idx);
}

static void __l2x0_pmu_enable(void)
{
	u32 val = readl_relaxed(l2x0_base + L2X0_EVENT_CNT_CTRL);
	val |= L2X0_EVENT_CNT_CTRL_ENABLE;
	writel_relaxed(val, l2x0_base + L2X0_EVENT_CNT_CTRL);
}

static void __l2x0_pmu_disable(void)
{
	u32 val = readl_relaxed(l2x0_base + L2X0_EVENT_CNT_CTRL);
	val &= ~L2X0_EVENT_CNT_CTRL_ENABLE;
	writel_relaxed(val, l2x0_base + L2X0_EVENT_CNT_CTRL);
}

static void l2x0_pmu_enable(struct pmu *pmu)
{
	if (l2x0_pmu_num_active_counters() == 0)
		return;

	__l2x0_pmu_enable();
}

static void l2x0_pmu_disable(struct pmu *pmu)
{
	if (l2x0_pmu_num_active_counters() == 0)
		return;

	__l2x0_pmu_disable();
}

static void warn_if_saturated(u32 count)
{
	if (count != 0xffffffff)
		return;

	pr_warn_ratelimited("L2X0 counter saturated. Poll period too long\n");
}

static void l2x0_pmu_event_read(struct perf_event *event)
{
	struct hw_perf_event *hw = &event->hw;
	u64 prev_count, new_count, mask;

	do {
		 prev_count = local64_read(&hw->prev_count);
		 new_count = l2x0_pmu_counter_read(hw->idx);
	} while (local64_xchg(&hw->prev_count, new_count) != prev_count);

	mask = GENMASK_ULL(31, 0);
	local64_add((new_count - prev_count) & mask, &event->count);

	warn_if_saturated(new_count);
}

static void l2x0_pmu_event_configure(struct perf_event *event)
{
	struct hw_perf_event *hw = &event->hw;

	/*
	 * The L2X0 counters saturate at 0xffffffff rather than wrapping, so we
	 * will *always* lose some number of events when a counter saturates,
	 * and have no way of detecting how many were lost.
	 *
	 * To minimize the impact of this, we try to maximize the period by
	 * always starting counters at zero. To ensure that group ratios are
	 * representative, we poll periodically to avoid counters saturating.
	 * See l2x0_pmu_poll().
	 */
	local64_set(&hw->prev_count, 0);
	l2x0_pmu_counter_write(hw->idx, 0);
}

static enum hrtimer_restart l2x0_pmu_poll(struct hrtimer *hrtimer)
{
	unsigned long flags;
	int i;

	local_irq_save(flags);
	__l2x0_pmu_disable();

	for (i = 0; i < PMU_NR_COUNTERS; i++) {
		struct perf_event *event = events[i];

		if (!event)
			continue;

		l2x0_pmu_event_read(event);
		l2x0_pmu_event_configure(event);
	}

	__l2x0_pmu_enable();
	local_irq_restore(flags);

	hrtimer_forward_now(hrtimer, l2x0_pmu_poll_period);
	return HRTIMER_RESTART;
}


static void __l2x0_pmu_event_enable(int idx, u32 event)
{
	u32 val;

	val = event << L2X0_EVENT_CNT_CFG_SRC_SHIFT;
	val |= L2X0_EVENT_CNT_CFG_INT_DISABLED;
	l2x0_pmu_counter_config_write(idx, val);
}

static void l2x0_pmu_event_start(struct perf_event *event, int flags)
{
	struct hw_perf_event *hw = &event->hw;

	if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
		return;

	if (flags & PERF_EF_RELOAD) {
		WARN_ON_ONCE(!(hw->state & PERF_HES_UPTODATE));
		l2x0_pmu_event_configure(event);
	}

	hw->state = 0;

	__l2x0_pmu_event_enable(hw->idx, hw->config_base);
}

static void __l2x0_pmu_event_disable(int idx)
{
	u32 val;

	val = L2X0_EVENT_CNT_CFG_SRC_DISABLED << L2X0_EVENT_CNT_CFG_SRC_SHIFT;
	val |= L2X0_EVENT_CNT_CFG_INT_DISABLED;
	l2x0_pmu_counter_config_write(idx, val);
}

static void l2x0_pmu_event_stop(struct perf_event *event, int flags)
{
	struct hw_perf_event *hw = &event->hw;

	if (WARN_ON_ONCE(event->hw.state & PERF_HES_STOPPED))
		return;

	__l2x0_pmu_event_disable(hw->idx);

	hw->state |= PERF_HES_STOPPED;

	if (flags & PERF_EF_UPDATE) {
		l2x0_pmu_event_read(event);
		hw->state |= PERF_HES_UPTODATE;
	}
}

static int l2x0_pmu_event_add(struct perf_event *event, int flags)
{
	struct hw_perf_event *hw = &event->hw;
	int idx = l2x0_pmu_find_idx();

	if (idx == -1)
		return -EAGAIN;

	/*
	 * Pin the timer, so that the overflows are handled by the chosen
	 * event->cpu (this is the same one as presented in "cpumask"
	 * attribute).
	 */
	if (l2x0_pmu_num_active_counters() == 0)
		hrtimer_start(&l2x0_pmu_hrtimer, l2x0_pmu_poll_period,
			      HRTIMER_MODE_REL_PINNED);

	events[idx] = event;
	hw->idx = idx;

	l2x0_pmu_event_configure(event);

	hw->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;

	if (flags & PERF_EF_START)
		l2x0_pmu_event_start(event, 0);

	return 0;
}

static void l2x0_pmu_event_del(struct perf_event *event, int flags)
{
	struct hw_perf_event *hw = &event->hw;

	l2x0_pmu_event_stop(event, PERF_EF_UPDATE);

	events[hw->idx] = NULL;
	hw->idx = -1;

	if (l2x0_pmu_num_active_counters() == 0)
		hrtimer_cancel(&l2x0_pmu_hrtimer);
}

static bool l2x0_pmu_group_is_valid(struct perf_event *event)
{
	struct pmu *pmu = event->pmu;
	struct perf_event *leader = event->group_leader;
	struct perf_event *sibling;
	int num_hw = 0;

	if (leader->pmu == pmu)
		num_hw++;
	else if (!is_software_event(leader))
		return false;

	for_each_sibling_event(sibling, leader) {
		if (sibling->pmu == pmu)
			num_hw++;
		else if (!is_software_event(sibling))
			return false;
	}

	return num_hw <= PMU_NR_COUNTERS;
}

static int l2x0_pmu_event_init(struct perf_event *event)
{
	struct hw_perf_event *hw = &event->hw;

	if (event->attr.type != l2x0_pmu->type)
		return -ENOENT;

	if (is_sampling_event(event) ||
	    event->attach_state & PERF_ATTACH_TASK)
		return -EINVAL;

	if (event->cpu < 0)
		return -EINVAL;

	if (event->attr.config & ~L2X0_EVENT_CNT_CFG_SRC_MASK)
		return -EINVAL;

	hw->config_base = event->attr.config;

	if (!l2x0_pmu_group_is_valid(event))
		return -EINVAL;

	event->cpu = cpumask_first(&pmu_cpu);

	return 0;
}

struct l2x0_event_attribute {
	struct device_attribute attr;
	unsigned int config;
	bool pl310_only;
};

#define L2X0_EVENT_ATTR(_name, _config, _pl310_only)				\
	(&((struct l2x0_event_attribute[]) {{					\
		.attr = __ATTR(_name, S_IRUGO, l2x0_pmu_event_show, NULL),	\
		.config = _config,						\
		.pl310_only = _pl310_only,					\
	}})[0].attr.attr)

#define L220_PLUS_EVENT_ATTR(_name, _config)					\
	L2X0_EVENT_ATTR(_name, _config, false)

#define PL310_EVENT_ATTR(_name, _config)					\
	L2X0_EVENT_ATTR(_name, _config, true)

static ssize_t l2x0_pmu_event_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	struct l2x0_event_attribute *lattr;

	lattr = container_of(attr, typeof(*lattr), attr);
	return snprintf(buf, PAGE_SIZE, "config=0x%x\n", lattr->config);
}

static umode_t l2x0_pmu_event_attr_is_visible(struct kobject *kobj,
					      struct attribute *attr,
					      int unused)
{
	struct device *dev = kobj_to_dev(kobj);
	struct pmu *pmu = dev_get_drvdata(dev);
	struct l2x0_event_attribute *lattr;

	lattr = container_of(attr, typeof(*lattr), attr.attr);

	if (!lattr->pl310_only || strcmp("l2c_310", pmu->name) == 0)
		return attr->mode;

	return 0;
}

static struct attribute *l2x0_pmu_event_attrs[] = {
	L220_PLUS_EVENT_ATTR(co,	0x1),
	L220_PLUS_EVENT_ATTR(drhit,	0x2),
	L220_PLUS_EVENT_ATTR(drreq,	0x3),
	L220_PLUS_EVENT_ATTR(dwhit,	0x4),
	L220_PLUS_EVENT_ATTR(dwreq,	0x5),
	L220_PLUS_EVENT_ATTR(dwtreq,	0x6),
	L220_PLUS_EVENT_ATTR(irhit,	0x7),
	L220_PLUS_EVENT_ATTR(irreq,	0x8),
	L220_PLUS_EVENT_ATTR(wa,	0x9),
	PL310_EVENT_ATTR(ipfalloc,	0xa),
	PL310_EVENT_ATTR(epfhit,	0xb),
	PL310_EVENT_ATTR(epfalloc,	0xc),
	PL310_EVENT_ATTR(srrcvd,	0xd),
	PL310_EVENT_ATTR(srconf,	0xe),
	PL310_EVENT_ATTR(epfrcvd,	0xf),
	NULL
};

static struct attribute_group l2x0_pmu_event_attrs_group = {
	.name = "events",
	.attrs = l2x0_pmu_event_attrs,
	.is_visible = l2x0_pmu_event_attr_is_visible,
};

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

static struct device_attribute l2x0_pmu_cpumask_attr =
		__ATTR(cpumask, S_IRUGO, l2x0_pmu_cpumask_show, NULL);

static struct attribute *l2x0_pmu_cpumask_attrs[] = {
	&l2x0_pmu_cpumask_attr.attr,
	NULL,
};

static struct attribute_group l2x0_pmu_cpumask_attr_group = {
	.attrs = l2x0_pmu_cpumask_attrs,
};

static const struct attribute_group *l2x0_pmu_attr_groups[] = {
	&l2x0_pmu_event_attrs_group,
	&l2x0_pmu_cpumask_attr_group,
	NULL,
};

static void l2x0_pmu_reset(void)
{
	int i;

	__l2x0_pmu_disable();

	for (i = 0; i < PMU_NR_COUNTERS; i++)
		__l2x0_pmu_event_disable(i);
}

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

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

	target = cpumask_any_but(cpu_online_mask, cpu);
	if (target >= nr_cpu_ids)
		return 0;

	perf_pmu_migrate_context(l2x0_pmu, cpu, target);
	cpumask_set_cpu(target, &pmu_cpu);

	return 0;
}

void l2x0_pmu_suspend(void)
{
	int i;

	if (!l2x0_pmu)
		return;

	l2x0_pmu_disable(l2x0_pmu);

	for (i = 0; i < PMU_NR_COUNTERS; i++) {
		if (events[i])
			l2x0_pmu_event_stop(events[i], PERF_EF_UPDATE);
	}

}

void l2x0_pmu_resume(void)
{
	int i;

	if (!l2x0_pmu)
		return;

	l2x0_pmu_reset();

	for (i = 0; i < PMU_NR_COUNTERS; i++) {
		if (events[i])
			l2x0_pmu_event_start(events[i], PERF_EF_RELOAD);
	}

	l2x0_pmu_enable(l2x0_pmu);
}

void __init l2x0_pmu_register(void __iomem *base, u32 part)
{
	/*
	 * Determine whether we support the PMU, and choose the name for sysfs.
	 * This is also used by l2x0_pmu_event_attr_is_visible to determine
	 * which events to display, as the PL310 PMU supports a superset of
	 * L220 events.
	 *
	 * The L210 PMU has a different programmer's interface, and is not
	 * supported by this driver.
	 *
	 * We must defer registering the PMU until the perf subsystem is up and
	 * running, so just stash the name and base, and leave that to another
	 * initcall.
	 */
	switch (part & L2X0_CACHE_ID_PART_MASK) {
	case L2X0_CACHE_ID_PART_L220:
		l2x0_name = "l2c_220";
		break;
	case L2X0_CACHE_ID_PART_L310:
		l2x0_name = "l2c_310";
		break;
	default:
		return;
	}

	l2x0_base = base;
}

static __init int l2x0_pmu_init(void)
{
	int ret;

	if (!l2x0_base)
		return 0;

	l2x0_pmu = kzalloc(sizeof(*l2x0_pmu), GFP_KERNEL);
	if (!l2x0_pmu) {
		pr_warn("Unable to allocate L2x0 PMU\n");
		return -ENOMEM;
	}

	*l2x0_pmu = (struct pmu) {
		.task_ctx_nr = perf_invalid_context,
		.pmu_enable = l2x0_pmu_enable,
		.pmu_disable = l2x0_pmu_disable,
		.read = l2x0_pmu_event_read,
		.start = l2x0_pmu_event_start,
		.stop = l2x0_pmu_event_stop,
		.add = l2x0_pmu_event_add,
		.del = l2x0_pmu_event_del,
		.event_init = l2x0_pmu_event_init,
		.attr_groups = l2x0_pmu_attr_groups,
		.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
	};

	l2x0_pmu_reset();

	/*
	 * We always use a hrtimer rather than an interrupt.
	 * See comments in l2x0_pmu_event_configure and l2x0_pmu_poll.
	 *
	 * Polling once a second allows the counters to fill up to 1/128th on a
	 * quad-core test chip with cores clocked at 400MHz. Hopefully this
	 * leaves sufficient headroom to avoid overflow on production silicon
	 * at higher frequencies.
	 */
	l2x0_pmu_poll_period = ms_to_ktime(1000);
	hrtimer_init(&l2x0_pmu_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	l2x0_pmu_hrtimer.function = l2x0_pmu_poll;

	cpumask_set_cpu(0, &pmu_cpu);
	ret = cpuhp_setup_state_nocalls(CPUHP_AP_PERF_ARM_L2X0_ONLINE,
					"perf/arm/l2x0:online", NULL,
					l2x0_pmu_offline_cpu);
	if (ret)
		goto out_pmu;

	ret = perf_pmu_register(l2x0_pmu, l2x0_name, -1);
	if (ret)
		goto out_cpuhp;

	return 0;

out_cpuhp:
	cpuhp_remove_state_nocalls(CPUHP_AP_PERF_ARM_L2X0_ONLINE);
out_pmu:
	kfree(l2x0_pmu);
	l2x0_pmu = NULL;
	return ret;
}
device_initcall(l2x0_pmu_init);
