// SPDX-License-Identifier: GPL-2.0
/*
 * Linux performance counter support for LoongArch.
 *
 * Copyright (C) 2022 Loongson Technology Corporation Limited
 *
 * Derived from MIPS:
 * Copyright (C) 2010 MIPS Technologies, Inc.
 * Copyright (C) 2011 Cavium Networks, Inc.
 * Author: Deng-Cheng Zhu
 */

#include <linux/cpumask.h>
#include <linux/interrupt.h>
#include <linux/smp.h>
#include <linux/kernel.h>
#include <linux/perf_event.h>
#include <linux/uaccess.h>
#include <linux/sched/task_stack.h>

#include <asm/irq.h>
#include <asm/irq_regs.h>
#include <asm/stacktrace.h>
#include <asm/unwind.h>

/*
 * Get the return address for a single stackframe and return a pointer to the
 * next frame tail.
 */
static unsigned long
user_backtrace(struct perf_callchain_entry_ctx *entry, unsigned long fp)
{
	unsigned long err;
	unsigned long __user *user_frame_tail;
	struct stack_frame buftail;

	user_frame_tail = (unsigned long __user *)(fp - sizeof(struct stack_frame));

	/* Also check accessibility of one struct frame_tail beyond */
	if (!access_ok(user_frame_tail, sizeof(buftail)))
		return 0;

	pagefault_disable();
	err = __copy_from_user_inatomic(&buftail, user_frame_tail, sizeof(buftail));
	pagefault_enable();

	if (err || (unsigned long)user_frame_tail >= buftail.fp)
		return 0;

	perf_callchain_store(entry, buftail.ra);

	return buftail.fp;
}

void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
			 struct pt_regs *regs)
{
	unsigned long fp;

	if (perf_guest_state()) {
		/* We don't support guest os callchain now */
		return;
	}

	perf_callchain_store(entry, regs->csr_era);

	fp = regs->regs[22];

	while (entry->nr < entry->max_stack && fp && !((unsigned long)fp & 0xf))
		fp = user_backtrace(entry, fp);
}

void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
			   struct pt_regs *regs)
{
	struct unwind_state state;
	unsigned long addr;

	for (unwind_start(&state, current, regs);
	      !unwind_done(&state); unwind_next_frame(&state)) {
		addr = unwind_get_return_address(&state);
		if (!addr || perf_callchain_store(entry, addr))
			return;
	}
}

#define LOONGARCH_MAX_HWEVENTS 32

struct cpu_hw_events {
	/* Array of events on this cpu. */
	struct perf_event	*events[LOONGARCH_MAX_HWEVENTS];

	/*
	 * Set the bit (indexed by the counter number) when the counter
	 * is used for an event.
	 */
	unsigned long		used_mask[BITS_TO_LONGS(LOONGARCH_MAX_HWEVENTS)];

	/*
	 * Software copy of the control register for each performance counter.
	 */
	unsigned int		saved_ctrl[LOONGARCH_MAX_HWEVENTS];
};
static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
	.saved_ctrl = {0},
};

/* The description of LoongArch performance events. */
struct loongarch_perf_event {
	unsigned int event_id;
};

static struct loongarch_perf_event raw_event;
static DEFINE_MUTEX(raw_event_mutex);

#define C(x) PERF_COUNT_HW_CACHE_##x
#define HW_OP_UNSUPPORTED		0xffffffff
#define CACHE_OP_UNSUPPORTED		0xffffffff

#define PERF_MAP_ALL_UNSUPPORTED					\
	[0 ... PERF_COUNT_HW_MAX - 1] = {HW_OP_UNSUPPORTED}

#define PERF_CACHE_MAP_ALL_UNSUPPORTED					\
[0 ... C(MAX) - 1] = {							\
	[0 ... C(OP_MAX) - 1] = {					\
		[0 ... C(RESULT_MAX) - 1] = {CACHE_OP_UNSUPPORTED},	\
	},								\
}

struct loongarch_pmu {
	u64		max_period;
	u64		valid_count;
	u64		overflow;
	const char	*name;
	unsigned int	num_counters;
	u64		(*read_counter)(unsigned int idx);
	void		(*write_counter)(unsigned int idx, u64 val);
	const struct loongarch_perf_event *(*map_raw_event)(u64 config);
	const struct loongarch_perf_event (*general_event_map)[PERF_COUNT_HW_MAX];
	const struct loongarch_perf_event (*cache_event_map)
				[PERF_COUNT_HW_CACHE_MAX]
				[PERF_COUNT_HW_CACHE_OP_MAX]
				[PERF_COUNT_HW_CACHE_RESULT_MAX];
};

static struct loongarch_pmu loongarch_pmu;

#define M_PERFCTL_EVENT(event)	(event & CSR_PERFCTRL_EVENT)

#define M_PERFCTL_COUNT_EVENT_WHENEVER	(CSR_PERFCTRL_PLV0 |	\
					CSR_PERFCTRL_PLV1 |	\
					CSR_PERFCTRL_PLV2 |	\
					CSR_PERFCTRL_PLV3 |	\
					CSR_PERFCTRL_IE)

#define M_PERFCTL_CONFIG_MASK		0x1f0000

static void pause_local_counters(void);
static void resume_local_counters(void);

static u64 loongarch_pmu_read_counter(unsigned int idx)
{
	u64 val = -1;

	switch (idx) {
	case 0:
		val = read_csr_perfcntr0();
		break;
	case 1:
		val = read_csr_perfcntr1();
		break;
	case 2:
		val = read_csr_perfcntr2();
		break;
	case 3:
		val = read_csr_perfcntr3();
		break;
	default:
		WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx);
		return 0;
	}

	return val;
}

static void loongarch_pmu_write_counter(unsigned int idx, u64 val)
{
	switch (idx) {
	case 0:
		write_csr_perfcntr0(val);
		return;
	case 1:
		write_csr_perfcntr1(val);
		return;
	case 2:
		write_csr_perfcntr2(val);
		return;
	case 3:
		write_csr_perfcntr3(val);
		return;
	default:
		WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx);
		return;
	}
}

static unsigned int loongarch_pmu_read_control(unsigned int idx)
{
	unsigned int val = -1;

	switch (idx) {
	case 0:
		val = read_csr_perfctrl0();
		break;
	case 1:
		val = read_csr_perfctrl1();
		break;
	case 2:
		val = read_csr_perfctrl2();
		break;
	case 3:
		val = read_csr_perfctrl3();
		break;
	default:
		WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx);
		return 0;
	}

	return val;
}

static void loongarch_pmu_write_control(unsigned int idx, unsigned int val)
{
	switch (idx) {
	case 0:
		write_csr_perfctrl0(val);
		return;
	case 1:
		write_csr_perfctrl1(val);
		return;
	case 2:
		write_csr_perfctrl2(val);
		return;
	case 3:
		write_csr_perfctrl3(val);
		return;
	default:
		WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx);
		return;
	}
}

static int loongarch_pmu_alloc_counter(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc)
{
	int i;

	for (i = 0; i < loongarch_pmu.num_counters; i++) {
		if (!test_and_set_bit(i, cpuc->used_mask))
			return i;
	}

	return -EAGAIN;
}

static void loongarch_pmu_enable_event(struct hw_perf_event *evt, int idx)
{
	unsigned int cpu;
	struct perf_event *event = container_of(evt, struct perf_event, hw);
	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);

	WARN_ON(idx < 0 || idx >= loongarch_pmu.num_counters);

	/* Make sure interrupt enabled. */
	cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(evt->event_base) |
		(evt->config_base & M_PERFCTL_CONFIG_MASK) | CSR_PERFCTRL_IE;

	cpu = (event->cpu >= 0) ? event->cpu : smp_processor_id();

	/*
	 * We do not actually let the counter run. Leave it until start().
	 */
	pr_debug("Enabling perf counter for CPU%d\n", cpu);
}

static void loongarch_pmu_disable_event(int idx)
{
	unsigned long flags;
	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);

	WARN_ON(idx < 0 || idx >= loongarch_pmu.num_counters);

	local_irq_save(flags);
	cpuc->saved_ctrl[idx] = loongarch_pmu_read_control(idx) &
		~M_PERFCTL_COUNT_EVENT_WHENEVER;
	loongarch_pmu_write_control(idx, cpuc->saved_ctrl[idx]);
	local_irq_restore(flags);
}

static int loongarch_pmu_event_set_period(struct perf_event *event,
				    struct hw_perf_event *hwc,
				    int idx)
{
	int ret = 0;
	u64 left = local64_read(&hwc->period_left);
	u64 period = hwc->sample_period;

	if (unlikely((left + period) & (1ULL << 63))) {
		/* left underflowed by more than period. */
		left = period;
		local64_set(&hwc->period_left, left);
		hwc->last_period = period;
		ret = 1;
	} else	if (unlikely((left + period) <= period)) {
		/* left underflowed by less than period. */
		left += period;
		local64_set(&hwc->period_left, left);
		hwc->last_period = period;
		ret = 1;
	}

	if (left > loongarch_pmu.max_period) {
		left = loongarch_pmu.max_period;
		local64_set(&hwc->period_left, left);
	}

	local64_set(&hwc->prev_count, loongarch_pmu.overflow - left);

	loongarch_pmu.write_counter(idx, loongarch_pmu.overflow - left);

	perf_event_update_userpage(event);

	return ret;
}

static void loongarch_pmu_event_update(struct perf_event *event,
				 struct hw_perf_event *hwc,
				 int idx)
{
	u64 delta;
	u64 prev_raw_count, new_raw_count;

again:
	prev_raw_count = local64_read(&hwc->prev_count);
	new_raw_count = loongarch_pmu.read_counter(idx);

	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
				new_raw_count) != prev_raw_count)
		goto again;

	delta = new_raw_count - prev_raw_count;

	local64_add(delta, &event->count);
	local64_sub(delta, &hwc->period_left);
}

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

	if (flags & PERF_EF_RELOAD)
		WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));

	hwc->state = 0;

	/* Set the period for the event. */
	loongarch_pmu_event_set_period(event, hwc, hwc->idx);

	/* Enable the event. */
	loongarch_pmu_enable_event(hwc, hwc->idx);
}

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

	if (!(hwc->state & PERF_HES_STOPPED)) {
		/* We are working on a local event. */
		loongarch_pmu_disable_event(hwc->idx);
		barrier();
		loongarch_pmu_event_update(event, hwc, hwc->idx);
		hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
	}
}

static int loongarch_pmu_add(struct perf_event *event, int flags)
{
	int idx, err = 0;
	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
	struct hw_perf_event *hwc = &event->hw;

	perf_pmu_disable(event->pmu);

	/* To look for a free counter for this event. */
	idx = loongarch_pmu_alloc_counter(cpuc, hwc);
	if (idx < 0) {
		err = idx;
		goto out;
	}

	/*
	 * If there is an event in the counter we are going to use then
	 * make sure it is disabled.
	 */
	event->hw.idx = idx;
	loongarch_pmu_disable_event(idx);
	cpuc->events[idx] = event;

	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
	if (flags & PERF_EF_START)
		loongarch_pmu_start(event, PERF_EF_RELOAD);

	/* Propagate our changes to the userspace mapping. */
	perf_event_update_userpage(event);

out:
	perf_pmu_enable(event->pmu);
	return err;
}

static void loongarch_pmu_del(struct perf_event *event, int flags)
{
	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
	struct hw_perf_event *hwc = &event->hw;
	int idx = hwc->idx;

	WARN_ON(idx < 0 || idx >= loongarch_pmu.num_counters);

	loongarch_pmu_stop(event, PERF_EF_UPDATE);
	cpuc->events[idx] = NULL;
	clear_bit(idx, cpuc->used_mask);

	perf_event_update_userpage(event);
}

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

	/* Don't read disabled counters! */
	if (hwc->idx < 0)
		return;

	loongarch_pmu_event_update(event, hwc, hwc->idx);
}

static void loongarch_pmu_enable(struct pmu *pmu)
{
	resume_local_counters();
}

static void loongarch_pmu_disable(struct pmu *pmu)
{
	pause_local_counters();
}

static DEFINE_MUTEX(pmu_reserve_mutex);
static atomic_t active_events = ATOMIC_INIT(0);

static int get_pmc_irq(void)
{
	struct irq_domain *d = irq_find_matching_fwnode(cpuintc_handle, DOMAIN_BUS_ANY);

	if (d)
		return irq_create_mapping(d, EXCCODE_PMC - EXCCODE_INT_START);

	return -EINVAL;
}

static void reset_counters(void *arg);
static int __hw_perf_event_init(struct perf_event *event);

static void hw_perf_event_destroy(struct perf_event *event)
{
	if (atomic_dec_and_mutex_lock(&active_events, &pmu_reserve_mutex)) {
		on_each_cpu(reset_counters, NULL, 1);
		free_irq(get_pmc_irq(), &loongarch_pmu);
		mutex_unlock(&pmu_reserve_mutex);
	}
}

static void handle_associated_event(struct cpu_hw_events *cpuc, int idx,
			struct perf_sample_data *data, struct pt_regs *regs)
{
	struct perf_event *event = cpuc->events[idx];
	struct hw_perf_event *hwc = &event->hw;

	loongarch_pmu_event_update(event, hwc, idx);
	data->period = event->hw.last_period;
	if (!loongarch_pmu_event_set_period(event, hwc, idx))
		return;

	if (perf_event_overflow(event, data, regs))
		loongarch_pmu_disable_event(idx);
}

static irqreturn_t pmu_handle_irq(int irq, void *dev)
{
	int n;
	int handled = IRQ_NONE;
	uint64_t counter;
	struct pt_regs *regs;
	struct perf_sample_data data;
	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);

	/*
	 * First we pause the local counters, so that when we are locked
	 * here, the counters are all paused. When it gets locked due to
	 * perf_disable(), the timer interrupt handler will be delayed.
	 *
	 * See also loongarch_pmu_start().
	 */
	pause_local_counters();

	regs = get_irq_regs();

	perf_sample_data_init(&data, 0, 0);

	for (n = 0; n < loongarch_pmu.num_counters; n++) {
		if (test_bit(n, cpuc->used_mask)) {
			counter = loongarch_pmu.read_counter(n);
			if (counter & loongarch_pmu.overflow) {
				handle_associated_event(cpuc, n, &data, regs);
				handled = IRQ_HANDLED;
			}
		}
	}

	resume_local_counters();

	/*
	 * Do all the work for the pending perf events. We can do this
	 * in here because the performance counter interrupt is a regular
	 * interrupt, not NMI.
	 */
	if (handled == IRQ_HANDLED)
		irq_work_run();

	return handled;
}

static int loongarch_pmu_event_init(struct perf_event *event)
{
	int r, irq;
	unsigned long flags;

	/* does not support taken branch sampling */
	if (has_branch_stack(event))
		return -EOPNOTSUPP;

	switch (event->attr.type) {
	case PERF_TYPE_RAW:
	case PERF_TYPE_HARDWARE:
	case PERF_TYPE_HW_CACHE:
		break;

	default:
		/* Init it to avoid false validate_group */
		event->hw.event_base = 0xffffffff;
		return -ENOENT;
	}

	if (event->cpu >= 0 && !cpu_online(event->cpu))
		return -ENODEV;

	irq = get_pmc_irq();
	flags = IRQF_PERCPU | IRQF_NOBALANCING | IRQF_NO_THREAD | IRQF_NO_SUSPEND | IRQF_SHARED;
	if (!atomic_inc_not_zero(&active_events)) {
		mutex_lock(&pmu_reserve_mutex);
		if (atomic_read(&active_events) == 0) {
			r = request_irq(irq, pmu_handle_irq, flags, "Perf_PMU", &loongarch_pmu);
			if (r < 0) {
				mutex_unlock(&pmu_reserve_mutex);
				pr_warn("PMU IRQ request failed\n");
				return -ENODEV;
			}
		}
		atomic_inc(&active_events);
		mutex_unlock(&pmu_reserve_mutex);
	}

	return __hw_perf_event_init(event);
}

static struct pmu pmu = {
	.pmu_enable	= loongarch_pmu_enable,
	.pmu_disable	= loongarch_pmu_disable,
	.event_init	= loongarch_pmu_event_init,
	.add		= loongarch_pmu_add,
	.del		= loongarch_pmu_del,
	.start		= loongarch_pmu_start,
	.stop		= loongarch_pmu_stop,
	.read		= loongarch_pmu_read,
};

static unsigned int loongarch_pmu_perf_event_encode(const struct loongarch_perf_event *pev)
{
	return M_PERFCTL_EVENT(pev->event_id);
}

static const struct loongarch_perf_event *loongarch_pmu_map_general_event(int idx)
{
	const struct loongarch_perf_event *pev;

	pev = &(*loongarch_pmu.general_event_map)[idx];

	if (pev->event_id == HW_OP_UNSUPPORTED)
		return ERR_PTR(-ENOENT);

	return pev;
}

static const struct loongarch_perf_event *loongarch_pmu_map_cache_event(u64 config)
{
	unsigned int cache_type, cache_op, cache_result;
	const struct loongarch_perf_event *pev;

	cache_type = (config >> 0) & 0xff;
	if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
		return ERR_PTR(-EINVAL);

	cache_op = (config >> 8) & 0xff;
	if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
		return ERR_PTR(-EINVAL);

	cache_result = (config >> 16) & 0xff;
	if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
		return ERR_PTR(-EINVAL);

	pev = &((*loongarch_pmu.cache_event_map)
					[cache_type]
					[cache_op]
					[cache_result]);

	if (pev->event_id == CACHE_OP_UNSUPPORTED)
		return ERR_PTR(-ENOENT);

	return pev;
}

static int validate_group(struct perf_event *event)
{
	struct cpu_hw_events fake_cpuc;
	struct perf_event *sibling, *leader = event->group_leader;

	memset(&fake_cpuc, 0, sizeof(fake_cpuc));

	if (loongarch_pmu_alloc_counter(&fake_cpuc, &leader->hw) < 0)
		return -EINVAL;

	for_each_sibling_event(sibling, leader) {
		if (loongarch_pmu_alloc_counter(&fake_cpuc, &sibling->hw) < 0)
			return -EINVAL;
	}

	if (loongarch_pmu_alloc_counter(&fake_cpuc, &event->hw) < 0)
		return -EINVAL;

	return 0;
}

static void reset_counters(void *arg)
{
	int n;
	int counters = loongarch_pmu.num_counters;

	for (n = 0; n < counters; n++) {
		loongarch_pmu_write_control(n, 0);
		loongarch_pmu.write_counter(n, 0);
	}
}

static const struct loongarch_perf_event loongson_event_map[PERF_COUNT_HW_MAX] = {
	PERF_MAP_ALL_UNSUPPORTED,
	[PERF_COUNT_HW_CPU_CYCLES] = { 0x00 },
	[PERF_COUNT_HW_INSTRUCTIONS] = { 0x01 },
	[PERF_COUNT_HW_CACHE_REFERENCES] = { 0x08 },
	[PERF_COUNT_HW_CACHE_MISSES] = { 0x09 },
	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x02 },
	[PERF_COUNT_HW_BRANCH_MISSES] = { 0x03 },
};

static const struct loongarch_perf_event loongson_cache_map
				[PERF_COUNT_HW_CACHE_MAX]
				[PERF_COUNT_HW_CACHE_OP_MAX]
				[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
PERF_CACHE_MAP_ALL_UNSUPPORTED,
[C(L1D)] = {
	/*
	 * Like some other architectures (e.g. ARM), the performance
	 * counters don't differentiate between read and write
	 * accesses/misses, so this isn't strictly correct, but it's the
	 * best we can do. Writes and reads get combined.
	 */
	[C(OP_READ)] = {
		[C(RESULT_ACCESS)]	= { 0x8 },
		[C(RESULT_MISS)]	= { 0x9 },
	},
	[C(OP_WRITE)] = {
		[C(RESULT_ACCESS)]	= { 0x8 },
		[C(RESULT_MISS)]	= { 0x9 },
	},
	[C(OP_PREFETCH)] = {
		[C(RESULT_ACCESS)]	= { 0xaa },
		[C(RESULT_MISS)]	= { 0xa9 },
	},
},
[C(L1I)] = {
	[C(OP_READ)] = {
		[C(RESULT_ACCESS)]	= { 0x6 },
		[C(RESULT_MISS)]	= { 0x7 },
	},
},
[C(LL)] = {
	[C(OP_READ)] = {
		[C(RESULT_ACCESS)]	= { 0xc },
		[C(RESULT_MISS)]	= { 0xd },
	},
	[C(OP_WRITE)] = {
		[C(RESULT_ACCESS)]	= { 0xc },
		[C(RESULT_MISS)]	= { 0xd },
	},
},
[C(ITLB)] = {
	[C(OP_READ)] = {
		[C(RESULT_MISS)]    = { 0x3b },
	},
},
[C(DTLB)] = {
	[C(OP_READ)] = {
		[C(RESULT_ACCESS)]	= { 0x4 },
		[C(RESULT_MISS)]	= { 0x3c },
	},
	[C(OP_WRITE)] = {
		[C(RESULT_ACCESS)]	= { 0x4 },
		[C(RESULT_MISS)]	= { 0x3c },
	},
},
[C(BPU)] = {
	/* Using the same code for *HW_BRANCH* */
	[C(OP_READ)] = {
		[C(RESULT_ACCESS)]  = { 0x02 },
		[C(RESULT_MISS)]    = { 0x03 },
	},
},
};

static int __hw_perf_event_init(struct perf_event *event)
{
	int err;
	struct hw_perf_event *hwc = &event->hw;
	struct perf_event_attr *attr = &event->attr;
	const struct loongarch_perf_event *pev;

	/* Returning LoongArch event descriptor for generic perf event. */
	if (PERF_TYPE_HARDWARE == event->attr.type) {
		if (event->attr.config >= PERF_COUNT_HW_MAX)
			return -EINVAL;
		pev = loongarch_pmu_map_general_event(event->attr.config);
	} else if (PERF_TYPE_HW_CACHE == event->attr.type) {
		pev = loongarch_pmu_map_cache_event(event->attr.config);
	} else if (PERF_TYPE_RAW == event->attr.type) {
		/* We are working on the global raw event. */
		mutex_lock(&raw_event_mutex);
		pev = loongarch_pmu.map_raw_event(event->attr.config);
	} else {
		/* The event type is not (yet) supported. */
		return -EOPNOTSUPP;
	}

	if (IS_ERR(pev)) {
		if (PERF_TYPE_RAW == event->attr.type)
			mutex_unlock(&raw_event_mutex);
		return PTR_ERR(pev);
	}

	/*
	 * We allow max flexibility on how each individual counter shared
	 * by the single CPU operates (the mode exclusion and the range).
	 */
	hwc->config_base = CSR_PERFCTRL_IE;

	hwc->event_base = loongarch_pmu_perf_event_encode(pev);
	if (PERF_TYPE_RAW == event->attr.type)
		mutex_unlock(&raw_event_mutex);

	if (!attr->exclude_user) {
		hwc->config_base |= CSR_PERFCTRL_PLV3;
		hwc->config_base |= CSR_PERFCTRL_PLV2;
	}
	if (!attr->exclude_kernel) {
		hwc->config_base |= CSR_PERFCTRL_PLV0;
	}
	if (!attr->exclude_hv) {
		hwc->config_base |= CSR_PERFCTRL_PLV1;
	}

	hwc->config_base &= M_PERFCTL_CONFIG_MASK;
	/*
	 * The event can belong to another cpu. We do not assign a local
	 * counter for it for now.
	 */
	hwc->idx = -1;
	hwc->config = 0;

	if (!hwc->sample_period) {
		hwc->sample_period  = loongarch_pmu.max_period;
		hwc->last_period    = hwc->sample_period;
		local64_set(&hwc->period_left, hwc->sample_period);
	}

	err = 0;
	if (event->group_leader != event)
		err = validate_group(event);

	event->destroy = hw_perf_event_destroy;

	if (err)
		event->destroy(event);

	return err;
}

static void pause_local_counters(void)
{
	unsigned long flags;
	int ctr = loongarch_pmu.num_counters;
	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);

	local_irq_save(flags);
	do {
		ctr--;
		cpuc->saved_ctrl[ctr] = loongarch_pmu_read_control(ctr);
		loongarch_pmu_write_control(ctr, cpuc->saved_ctrl[ctr] &
					 ~M_PERFCTL_COUNT_EVENT_WHENEVER);
	} while (ctr > 0);
	local_irq_restore(flags);
}

static void resume_local_counters(void)
{
	int ctr = loongarch_pmu.num_counters;
	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);

	do {
		ctr--;
		loongarch_pmu_write_control(ctr, cpuc->saved_ctrl[ctr]);
	} while (ctr > 0);
}

static const struct loongarch_perf_event *loongarch_pmu_map_raw_event(u64 config)
{
	raw_event.event_id = M_PERFCTL_EVENT(config);

	return &raw_event;
}

static int __init init_hw_perf_events(void)
{
	int counters;

	if (!cpu_has_pmp)
		return -ENODEV;

	pr_info("Performance counters: ");
	counters = ((read_cpucfg(LOONGARCH_CPUCFG6) & CPUCFG6_PMNUM) >> 4) + 1;

	loongarch_pmu.num_counters = counters;
	loongarch_pmu.max_period = (1ULL << 63) - 1;
	loongarch_pmu.valid_count = (1ULL << 63) - 1;
	loongarch_pmu.overflow = 1ULL << 63;
	loongarch_pmu.name = "loongarch/loongson64";
	loongarch_pmu.read_counter = loongarch_pmu_read_counter;
	loongarch_pmu.write_counter = loongarch_pmu_write_counter;
	loongarch_pmu.map_raw_event = loongarch_pmu_map_raw_event;
	loongarch_pmu.general_event_map = &loongson_event_map;
	loongarch_pmu.cache_event_map = &loongson_cache_map;

	on_each_cpu(reset_counters, NULL, 1);

	pr_cont("%s PMU enabled, %d %d-bit counters available to each CPU.\n",
			loongarch_pmu.name, counters, 64);

	perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);

	return 0;
}
early_initcall(init_hw_perf_events);
