/*
 * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that 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.
 */

#include <linux/irq.h>
#include <asm/pmu.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>

#include <mach/msm-krait-l2-accessors.h>

#define PMU_CODES_SIZE 64

/*
 * The L2 PMU is shared between all CPU's, so protect
 * its bitmap access.
 */
struct pmu_constraints {
	u64 pmu_bitmap;
	u8 codes[PMU_CODES_SIZE];
	raw_spinlock_t lock;
} l2_pmu_constraints = {
	.pmu_bitmap = 0,
	.codes = {-1},
	.lock = __RAW_SPIN_LOCK_UNLOCKED(l2_pmu_constraints.lock),
};

/* NRCCG format for perf RAW codes. */
PMU_FORMAT_ATTR(l2_prefix, "config:16-19");
PMU_FORMAT_ATTR(l2_reg,	"config:12-15");
PMU_FORMAT_ATTR(l2_code, "config:4-11");
PMU_FORMAT_ATTR(l2_grp,	"config:0-3");

static struct attribute *msm_l2_ev_formats[] = {
	&format_attr_l2_prefix.attr,
	&format_attr_l2_reg.attr,
	&format_attr_l2_code.attr,
	&format_attr_l2_grp.attr,
	NULL,
};

/*
 * Format group is essential to access PMU's from userspace
 * via their .name field.
 */
static struct attribute_group msm_l2_pmu_format_group = {
	.name = "format",
	.attrs = msm_l2_ev_formats,
};

static const struct attribute_group *msm_l2_pmu_attr_grps[] = {
	&msm_l2_pmu_format_group,
	NULL,
};

static u32 l2_orig_filter_prefix = 0x000f0030;

/* L2 slave port traffic filtering */
static u32 l2_slv_filter_prefix = 0x000f0010;

static int total_l2_ctrs;
static int l2_cycle_ctr_idx;

static u32 pmu_type;

static struct arm_pmu krait_l2_pmu;

static struct perf_event *l2_events[MAX_KRAIT_L2_CTRS];
static unsigned long l2_used_mask[BITS_TO_LONGS(MAX_KRAIT_L2_CTRS)];

static struct pmu_hw_events krait_l2_pmu_hw_events = {
	.events = l2_events,
	.used_mask = l2_used_mask,
	.pmu_lock = __RAW_SPIN_LOCK_UNLOCKED(krait_l2_pmu_hw_events.pmu_lock),
};

struct event_desc {
	int event_groupsel;
	int event_reg;
	int event_group_code;
};

static struct pmu_hw_events *krait_l2_get_hw_events(void)
{
	return &krait_l2_pmu_hw_events;
}

void get_event_desc(u64 config, struct event_desc *evdesc)
{
	/* L2PMEVCNTRX */
	evdesc->event_reg = (config & EVENT_REG_MASK) >> EVENT_REG_SHIFT;
	/* Group code (row ) */
	evdesc->event_group_code =
	    (config & EVENT_GROUPCODE_MASK) >> EVENT_GROUPCODE_SHIFT;
	/* Group sel (col) */
	evdesc->event_groupsel = (config & EVENT_GROUPSEL_MASK);

	pr_debug("%s: reg: %x, group_code: %x, groupsel: %x\n", __func__,
		 evdesc->event_reg, evdesc->event_group_code,
		 evdesc->event_groupsel);
}

static void set_evcntcr(int ctr)
{
	u32 evtcr_reg = (ctr * 16) + IA_L2PMXEVCNTCR_BASE;

	set_l2_indirect_reg(evtcr_reg, 0x0);
}

static void set_evtyper(int event_groupsel, int event_reg, int ctr)
{
	u32 evtype_reg = (ctr * 16) + IA_L2PMXEVTYPER_BASE;
	u32 evtype_val = event_groupsel + (4 * event_reg);

	set_l2_indirect_reg(evtype_reg, evtype_val);
}

static void set_evres(int event_groupsel, int event_reg, int event_group_code)
{
	u32 group_reg = event_reg + IA_L2PMRESX_BASE;
	u32 group_val =
		RESRX_VALUE_EN | (event_group_code << (8 * event_groupsel));
	u32 resr_val;
	u32 group_byte = 0xff;
	u32 group_mask = ~(group_byte << (8 * event_groupsel));

	resr_val = get_l2_indirect_reg(group_reg);
	resr_val &= group_mask;
	resr_val |= group_val;

	set_l2_indirect_reg(group_reg, resr_val);
}

static void set_evfilter_task_mode(int ctr, unsigned int is_slv)
{
	u32 filter_reg = (ctr * 16) + IA_L2PMXEVFILTER_BASE;
	u32 filter_val = l2_orig_filter_prefix | 1 << smp_processor_id();

	if (is_slv)
		filter_val = l2_slv_filter_prefix;

	set_l2_indirect_reg(filter_reg, filter_val);
}

static void set_evfilter_sys_mode(int ctr, unsigned int is_slv, int cpu,
		unsigned int is_tracectr)
{
	u32 filter_reg = (ctr * 16) + IA_L2PMXEVFILTER_BASE;
	u32 filter_val = l2_orig_filter_prefix | 0xf;

	if (is_slv == 1)
		filter_val = l2_slv_filter_prefix;
	if (is_tracectr == 1)
		filter_val = l2_orig_filter_prefix | 1 << cpu;

	set_l2_indirect_reg(filter_reg, filter_val);
}

static void enable_intenset(u32 idx)
{
	if (idx == l2_cycle_ctr_idx)
		set_l2_indirect_reg(L2PMINTENSET, 1 << L2CYCLE_CTR_BIT);
	else
		set_l2_indirect_reg(L2PMINTENSET, 1 << idx);
}

static void disable_intenclr(u32 idx)
{
	if (idx == l2_cycle_ctr_idx)
		set_l2_indirect_reg(L2PMINTENCLR, 1 << L2CYCLE_CTR_BIT);
	else
		set_l2_indirect_reg(L2PMINTENCLR, 1 << idx);
}

static void enable_counter(u32 idx)
{
	if (idx == l2_cycle_ctr_idx)
		set_l2_indirect_reg(L2PMCNTENSET, 1 << L2CYCLE_CTR_BIT);
	else
		set_l2_indirect_reg(L2PMCNTENSET, 1 << idx);
}

static void disable_counter(u32 idx)
{
	if (idx == l2_cycle_ctr_idx)
		set_l2_indirect_reg(L2PMCNTENCLR, 1 << L2CYCLE_CTR_BIT);
	else
		set_l2_indirect_reg(L2PMCNTENCLR, 1 << idx);
}

static u32 krait_l2_read_counter(int idx)
{
	u32 val;
	u32 counter_reg = (idx * 16) + IA_L2PMXEVCNTR_BASE;

	if (idx == l2_cycle_ctr_idx)
		val = get_l2_indirect_reg(L2PMCCNTR);
	else
		val = get_l2_indirect_reg(counter_reg);

	return val;
}

static void krait_l2_write_counter(int idx, u32 val)
{
	u32 counter_reg = (idx * 16) + IA_L2PMXEVCNTR_BASE;

	if (idx == l2_cycle_ctr_idx)
		set_l2_indirect_reg(L2PMCCNTR, val);
	else
		set_l2_indirect_reg(counter_reg, val);
}

static void krait_l2_stop_counter(struct hw_perf_event *hwc, int idx)
{
	disable_intenclr(idx);
	disable_counter(idx);

	pr_debug("%s: event: %ld ctr: %d stopped\n", __func__,
			hwc->config_base, idx);
}

static void krait_l2_enable(struct hw_perf_event *hwc, int idx, int cpu)
{
	struct event_desc evdesc;
	unsigned long iflags;
	unsigned int is_slv = 0;
	unsigned int is_tracectr = 0;
	unsigned int evt_prefix;

	raw_spin_lock_irqsave(&krait_l2_pmu_hw_events.pmu_lock, iflags);

	if (hwc->config_base == L2CYCLE_CTR_RAW_CODE)
		goto out;

	/* Check if user requested any special origin filtering. */
	evt_prefix = (hwc->config_base &
			EVENT_PREFIX_MASK) >> EVENT_PREFIX_SHIFT;

	if (evt_prefix == L2_SLAVE_EV_PREFIX)
		is_slv = 1;
	else if (evt_prefix == L2_TRACECTR_PREFIX)
		is_tracectr = 1;

	set_evcntcr(idx);

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

	get_event_desc(hwc->config_base, &evdesc);

	set_evtyper(evdesc.event_groupsel, evdesc.event_reg, idx);

	set_evres(evdesc.event_groupsel, evdesc.event_reg,
		  evdesc.event_group_code);

	if (cpu < 0)
		set_evfilter_task_mode(idx, is_slv);
	else
		set_evfilter_sys_mode(idx, is_slv, cpu, is_tracectr);

out:
	enable_intenset(idx);
	enable_counter(idx);

	raw_spin_unlock_irqrestore(&krait_l2_pmu_hw_events.pmu_lock, iflags);

	pr_debug("%s: ctr: %d group: %ld group_code: %lld started from cpu:%d\n",
	     __func__, idx, hwc->config_base, hwc->config, smp_processor_id());
}

static void krait_l2_disable(struct hw_perf_event *hwc, int idx)
{
	unsigned long iflags;

	raw_spin_lock_irqsave(&krait_l2_pmu_hw_events.pmu_lock, iflags);

	krait_l2_stop_counter(hwc, idx);

	raw_spin_unlock_irqrestore(&krait_l2_pmu_hw_events.pmu_lock, iflags);

	pr_debug("%s: event: %ld deleted\n", __func__, hwc->config_base);

}

static int krait_l2_get_event_idx(struct pmu_hw_events *cpuc,
				  struct hw_perf_event *hwc)
{
	int ctr = 0;

	if (hwc->config_base == L2CYCLE_CTR_RAW_CODE) {
		if (test_and_set_bit(l2_cycle_ctr_idx, cpuc->used_mask))
			return -EAGAIN;

		return l2_cycle_ctr_idx;
	}

	for (ctr = 0; ctr < total_l2_ctrs - 1; ctr++) {
		if (!test_and_set_bit(ctr, cpuc->used_mask))
			return ctr;
	}

	return -EAGAIN;
}

static void krait_l2_start(void)
{
	isb();
	set_l2_indirect_reg(L2PMCR, L2PMCR_GLOBAL_ENABLE);
}

static void krait_l2_stop(void)
{
	set_l2_indirect_reg(L2PMCR, L2PMCR_GLOBAL_DISABLE);
	isb();
}

u32 get_reset_pmovsr(void)
{
	int val;

	val = get_l2_indirect_reg(L2PMOVSR);
	/* reset it */
	val &= 0xffffffff;
	set_l2_indirect_reg(L2PMOVSR, val);

	return val;
}

static irqreturn_t krait_l2_handle_irq(int irq_num, void *dev)
{
	unsigned long pmovsr;
	struct perf_sample_data data;
	struct pt_regs *regs;
	struct perf_event *event;
	struct hw_perf_event *hwc;
	int bitp;
	int idx = 0;

	pmovsr = get_reset_pmovsr();

	if (!(pmovsr & 0xffffffff))
		return IRQ_NONE;

	regs = get_irq_regs();

	perf_sample_data_init(&data, 0);

	while (pmovsr) {
		bitp = __ffs(pmovsr);

		if (bitp == L2CYCLE_CTR_BIT)
			idx = l2_cycle_ctr_idx;
		else
			idx = bitp;

		event = krait_l2_pmu_hw_events.events[idx];

		if (!event)
			goto next;

		if (!test_bit(idx, krait_l2_pmu_hw_events.used_mask))
			goto next;

		hwc = &event->hw;

		armpmu_event_update(event, hwc, idx);

		data.period = event->hw.last_period;

		if (!armpmu_event_set_period(event, hwc, idx))
			goto next;

		if (perf_event_overflow(event, &data, regs))
			disable_counter(hwc->idx);
next:
		pmovsr &= (pmovsr - 1);
	}

	irq_work_run();

	return IRQ_HANDLED;
}

static int krait_l2_map_event(struct perf_event *event)
{
	if (pmu_type > 0 && pmu_type == event->attr.type)
		return event->attr.config & L2_EVT_MASK;
	else
		return -ENOENT;
}

static int
krait_l2_pmu_generic_request_irq(int irq, irq_handler_t *handle_irq)
{
	return request_irq(irq, *handle_irq,
			IRQF_DISABLED | IRQF_NOBALANCING,
			"krait-l2-armpmu", NULL);
}

static void
krait_l2_pmu_generic_free_irq(int irq)
{
	if (irq >= 0)
		free_irq(irq, NULL);
}

static int msm_l2_test_set_ev_constraint(struct perf_event *event)
{
	u32 evt_type = event->attr.config & L2_EVT_MASK;
	u8 evt_prefix = (evt_type & EVENT_PREFIX_MASK) >> EVENT_PREFIX_SHIFT;
	u8 reg   = (evt_type & 0x0F000) >> 12;
	u8 group = evt_type & 0x0000F;
	u8 code = (evt_type & 0x00FF0) >> 4;
	unsigned long flags;
	int err = 0;
	u64 bitmap_t;
	u32 shift_idx;

	if (evt_prefix == L2_TRACECTR_PREFIX)
		return err;
	/*
	 * Cycle counter collision is detected in
	 * get_event_idx().
	 */
	if (evt_type == L2CYCLE_CTR_RAW_CODE)
		return err;

	raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);

	shift_idx = ((reg * 4) + group);

	if (shift_idx >= PMU_CODES_SIZE) {
		err =  -EINVAL;
		goto out;
	}

	bitmap_t = 1 << shift_idx;

	if (!(l2_pmu_constraints.pmu_bitmap & bitmap_t)) {
		l2_pmu_constraints.pmu_bitmap |= bitmap_t;
		l2_pmu_constraints.codes[shift_idx] = code;
		goto out;
	} else {
		/*
		 * If NRCCG's are identical,
		 * its not column exclusion.
		 */
		if (l2_pmu_constraints.codes[shift_idx] != code)
			err = -EPERM;
		else
			/*
			 * If the event is counted in syswide mode
			 * then we want to count only on one CPU
			 * and set its filter to count from all.
			 * This sets the event OFF on all but one
			 * CPU.
			 */
			if (!(event->cpu < 0)) {
				event->state = PERF_EVENT_STATE_OFF;
				event->attr.constraint_duplicate = 1;
			}
	}
out:
	raw_spin_unlock_irqrestore(&l2_pmu_constraints.lock, flags);
	return err;
}

static int msm_l2_clear_ev_constraint(struct perf_event *event)
{
	u32 evt_type = event->attr.config & L2_EVT_MASK;
	u8 evt_prefix = (evt_type & EVENT_PREFIX_MASK) >> EVENT_PREFIX_SHIFT;
	u8 reg   = (evt_type & 0x0F000) >> 12;
	u8 group =  evt_type & 0x0000F;
	unsigned long flags;
	u64 bitmap_t;
	u32 shift_idx;
	int err = 1;

	if (evt_prefix == L2_TRACECTR_PREFIX)
		return 1;
	raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);

	shift_idx = ((reg * 4) + group);
	if (shift_idx >= PMU_CODES_SIZE) {
		err = -EINVAL;
		goto out;
	}

	bitmap_t = 1 << shift_idx;

	/* Clear constraint bit. */
	l2_pmu_constraints.pmu_bitmap &= ~bitmap_t;

	/* Clear code. */
	l2_pmu_constraints.codes[shift_idx] = -1;

	raw_spin_unlock_irqrestore(&l2_pmu_constraints.lock, flags);
out:
	return err;
}

int get_num_events(void)
{
	int val;

	val = get_l2_indirect_reg(L2PMCR);

	/*
	 * Read bits 15:11 of the L2PMCR and add 1
	 * for the cycle counter.
	 */
	return ((val >> PMCR_NUM_EV_SHIFT) & PMCR_NUM_EV_MASK) + 1;
}

static struct arm_pmu krait_l2_pmu = {
	.id		=	ARM_PERF_PMU_ID_KRAIT_L2,
	.type		=	ARM_PMU_DEVICE_L2CC,
	.name		=	"Krait L2CC PMU",
	.start		=	krait_l2_start,
	.stop		=	krait_l2_stop,
	.handle_irq	=	krait_l2_handle_irq,
	.request_pmu_irq	= krait_l2_pmu_generic_request_irq,
	.free_pmu_irq		= krait_l2_pmu_generic_free_irq,
	.enable		=	krait_l2_enable,
	.disable	=	krait_l2_disable,
	.get_event_idx	=	krait_l2_get_event_idx,
	.read_counter	=	krait_l2_read_counter,
	.write_counter	=	krait_l2_write_counter,
	.map_event	=	krait_l2_map_event,
	.max_period	=	MAX_L2_PERIOD,
	.get_hw_events	=	krait_l2_get_hw_events,
	.test_set_event_constraints	= msm_l2_test_set_ev_constraint,
	.clear_event_constraints	= msm_l2_clear_ev_constraint,
	.pmu.attr_groups		= msm_l2_pmu_attr_grps,
};

/*
 * PMU platform driver and devicetree bindings.
 */
static struct of_device_id l2pmu_of_device_ids[] = {
	{.compatible = "qcom,l2-pmu"},
	{},
};

static int __devinit krait_l2_pmu_device_probe(struct platform_device *pdev)
{
	krait_l2_pmu.plat_device = pdev;

	if (!armpmu_register(&krait_l2_pmu, "msm-l2", -1))
		pmu_type = krait_l2_pmu.pmu.type;

	return 0;
}

static struct platform_driver krait_l2_pmu_driver = {
	.driver		= {
		.name	= "l2-pmu",
		.of_match_table = l2pmu_of_device_ids,
	},
	.probe		= krait_l2_pmu_device_probe,
};

static int __init register_krait_l2_pmu_driver(void)
{
	int i;

	/* Reset all ctrs */
	set_l2_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);

	/* Get num of counters in the L2cc PMU. */
	total_l2_ctrs = get_num_events();
	krait_l2_pmu.num_events	= total_l2_ctrs;

	pr_info("Detected %d counters on the L2CC PMU.\n",
			total_l2_ctrs);

	/*
	 * The L2 cycle counter index in the used_mask
	 * bit stream is always after the other counters.
	 * Counter indexes begin from 0 to keep it consistent
	 * with the h/w.
	 */
	l2_cycle_ctr_idx = total_l2_ctrs - 1;

	/* Avoid spurious interrupt if any */
	get_reset_pmovsr();

	/* Clear counter enables */
	disable_counter(l2_cycle_ctr_idx);
	for (i = 0; i < total_l2_ctrs; i++)
		disable_counter(i);

	return platform_driver_register(&krait_l2_pmu_driver);
}
device_initcall(register_krait_l2_pmu_driver);
