/* Copyright (c) 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.
 */

/**
 * This file contains the part of the IOMMUv1 PMU driver that actually touches
 * IOMMU PMU registers.
 */

#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <mach/iommu_hw-v1.h>
#include <mach/iommu_perfmon.h>

#define PMCR_P_MASK		(0x1)
#define PMCR_P_SHIFT		(1)
#define PMCR_P			(PMCR_P_MASK << PMCR_P_SHIFT)
#define PMCFGR_NCG_MASK		(0xFF)
#define PMCFGR_NCG_SHIFT	(24)
#define PMCFGR_NCG		(PMCFGR_NCG_MASK << PMCFGR_NCG_SHIFT)
#define PMCFGR_N_MASK		(0xFF)
#define PMCFGR_N_SHIFT		(0)
#define PMCFGR_N		(PMCFGR_N_MASK << PMCFGR_N_SHIFT)
#define CR_E			0x1
#define CGCR_CEN		0x800
#define CGCR_CEN_SHFT		(1 << 11)
#define PMCGCR_CGNC_MASK	(0x0F)
#define PMCGCR_CGNC_SHIFT	(24)
#define PMCGCR_CGNC		(PMCGCR_CGNC_MASK << PMCGCR_CGNC_SHIFT)
#define PMCGCR_(group)		(PMCGCR_N + group*4)

#define PMOVSCLR_(n)		(PMOVSCLR_N + n*4)
#define PMCNTENSET_(n)		(PMCNTENSET_N + n*4)
#define PMCNTENCLR_(n)		(PMCNTENCLR_N + n*4)
#define PMINTENSET_(n)		(PMINTENSET_N + n*4)
#define PMINTENCLR_(n)		(PMINTENCLR_N + n*4)

#define PMEVCNTR_(n)		(PMEVCNTR_N + n*4)
#define PMEVTYPER_(n)		(PMEVTYPER_N + n*4)


static unsigned int iommu_pm_is_hw_access_OK(const struct iommu_pmon *pmon)
{
	/*
	 * IOMMUv1 is not in the always on domain so we need to make sure
	 * the regulators are turned on in addition to clocks before we allow
	 * access to the hardware thus we check if we have attached to the
	 * IOMMU in addition to checking if we have enabled PMU.
	 */
	return pmon->enabled && (pmon->iommu_attach_count > 0);
}

static void iommu_pm_grp_enable(struct iommu_info *iommu, unsigned int grp_no)
{
	unsigned int pmcgcr;
	pmcgcr = readl_relaxed(iommu->base + PMCGCR_(grp_no));
	pmcgcr |= CGCR_CEN;
	writel_relaxed(pmcgcr, iommu->base + PMCGCR_(grp_no));
}

static void iommu_pm_grp_disable(struct iommu_info *iommu, unsigned int grp_no)
{
	unsigned int pmcgcr;
	pmcgcr = readl_relaxed(iommu->base + PMCGCR_(grp_no));
	pmcgcr &= ~CGCR_CEN;
	writel_relaxed(pmcgcr, iommu->base + PMCGCR_(grp_no));
}

static void iommu_pm_enable(struct iommu_info *iommu)
{
	unsigned int pmcr;
	pmcr = readl_relaxed(iommu->base + PMCR);
	pmcr |= CR_E;
	writel_relaxed(pmcr, iommu->base + PMCR);
}

static void iommu_pm_disable(struct iommu_info *iommu)
{
	unsigned int pmcr;
	pmcr = readl_relaxed(iommu->base + PMCR);
	pmcr &= ~CR_E;
	writel_relaxed(pmcr, iommu->base + PMCR);
}

static void iommu_pm_reset_counters(const struct iommu_info *iommu)
{
	unsigned int pmcr;
	pmcr = readl_relaxed(iommu->base + PMCR);
	pmcr |= PMCR_P;
	writel_relaxed(pmcr, iommu->base + PMCR);
}

static void iommu_pm_check_for_overflow(struct iommu_pmon *pmon)
{
	struct iommu_pmon_counter *counter;
	struct iommu_info *iommu = &pmon->iommu;
	unsigned int reg_no = 0;
	unsigned int bit_no;
	unsigned int reg_value;
	unsigned int i;
	unsigned int j;
	unsigned int curr_reg = 0;

	reg_value = readl_relaxed(iommu->base + PMOVSCLR_(curr_reg));

	for (i = 0; i < pmon->num_groups; ++i) {
		struct iommu_pmon_cnt_group *cnt_grp = &pmon->cnt_grp[i];
		for (j = 0; j < cnt_grp->num_counters; ++j) {
			counter = &cnt_grp->counters[j];
			reg_no = counter->absolute_counter_no / 32;
			bit_no = counter->absolute_counter_no % 32;
			if (reg_no != curr_reg) {
				/* Clear overflow bits */
				writel_relaxed(reg_value, iommu->base +
					       PMOVSCLR_(reg_no));
				curr_reg = reg_no;
				reg_value = readl_relaxed(iommu->base +
							  PMOVSCLR_(curr_reg));
			}

			if (counter->enabled) {
				if (reg_value & (1 << bit_no))
					counter->overflow_count++;
			}
		}
	}

	/* Clear overflow */
	writel_relaxed(reg_value, iommu->base + PMOVSCLR_(reg_no));
}

static irqreturn_t iommu_pm_evt_ovfl_int_handler(int irq, void *dev_id)
{
	struct iommu_pmon *pmon = dev_id;
	struct iommu_info *iommu = &pmon->iommu;

	mutex_lock(&pmon->lock);

	if (!iommu_pm_is_hw_access_OK(pmon)) {
		mutex_unlock(&pmon->lock);
		goto out;
	}

	iommu->ops->iommu_lock_acquire();
	iommu_pm_check_for_overflow(pmon);
	iommu->ops->iommu_lock_release();

	mutex_unlock(&pmon->lock);

out:
	return IRQ_HANDLED;
}

static void iommu_pm_counter_enable(struct iommu_info *iommu,
				    struct iommu_pmon_counter *counter)
{
	unsigned int reg_no = counter->absolute_counter_no / 32;
	unsigned int bit_no = counter->absolute_counter_no % 32;
	unsigned int reg_value;

	/* Clear overflow of counter */
	reg_value = 1 << bit_no;
	writel_relaxed(reg_value, iommu->base + PMOVSCLR_(reg_no));

	/* Enable counter */
	writel_relaxed(reg_value, iommu->base + PMCNTENSET_(reg_no));
	counter->enabled = 1;
}

static void iommu_pm_counter_disable(struct iommu_info *iommu,
				     struct iommu_pmon_counter *counter)
{
	unsigned int reg_no = counter->absolute_counter_no / 32;
	unsigned int bit_no = counter->absolute_counter_no % 32;
	unsigned int reg_value;

	counter->enabled = 0;

	/* Disable counter */
	reg_value = 1 << bit_no;
	writel_relaxed(reg_value, iommu->base + PMCNTENCLR_(reg_no));

	/* Clear overflow of counter */
	writel_relaxed(reg_value, iommu->base + PMOVSCLR_(reg_no));
}

/*
 * Must be called after iommu_start_access() is called
 */
static void iommu_pm_ovfl_int_enable(struct iommu_info *iommu,
				     const struct iommu_pmon_counter *counter)
{
	unsigned int reg_no = counter->absolute_counter_no / 32;
	unsigned int bit_no = counter->absolute_counter_no % 32;
	unsigned int reg_value;

	/* Enable overflow interrupt for counter */
	reg_value = (1 << bit_no);
	writel_relaxed(reg_value, iommu->base + PMINTENSET_(reg_no));
}

/*
 * Must be called after iommu_start_access() is called
 */
static void iommu_pm_ovfl_int_disable(struct iommu_info *iommu,
				      const struct iommu_pmon_counter *counter)
{
	unsigned int reg_no = counter->absolute_counter_no / 32;
	unsigned int bit_no = counter->absolute_counter_no % 32;
	unsigned int reg_value;

	/* Disable overflow interrupt for counter */
	reg_value = 1 << bit_no;
	writel_relaxed(reg_value, iommu->base + PMINTENCLR_(reg_no));
}

static void iommu_pm_set_event_class(struct iommu_pmon *pmon,
				    unsigned int count_no,
				    unsigned int event_class)
{
	writel_relaxed(event_class, pmon->iommu.base + PMEVTYPER_(count_no));
}

static unsigned int iommu_pm_read_counter(struct iommu_pmon_counter *counter)
{
	struct iommu_pmon *pmon = counter->cnt_group->pmon;
	struct iommu_info *info = &pmon->iommu;
	unsigned int cnt_no = counter->absolute_counter_no;
	return readl_relaxed(info->base + PMEVCNTR_(cnt_no));
}

static void iommu_pm_initialize_hw(const struct iommu_pmon *pmon)
{
	/* No initialization needed */
}

static struct iommu_pm_hw_ops iommu_pm_hw_ops = {
	.initialize_hw = iommu_pm_initialize_hw,
	.is_hw_access_OK = iommu_pm_is_hw_access_OK,
	.grp_enable = iommu_pm_grp_enable,
	.grp_disable = iommu_pm_grp_disable,
	.enable_pm = iommu_pm_enable,
	.disable_pm = iommu_pm_disable,
	.reset_counters = iommu_pm_reset_counters,
	.check_for_overflow = iommu_pm_check_for_overflow,
	.evt_ovfl_int_handler = iommu_pm_evt_ovfl_int_handler,
	.counter_enable = iommu_pm_counter_enable,
	.counter_disable = iommu_pm_counter_disable,
	.ovfl_int_enable = iommu_pm_ovfl_int_enable,
	.ovfl_int_disable = iommu_pm_ovfl_int_disable,
	.set_event_class = iommu_pm_set_event_class,
	.read_counter = iommu_pm_read_counter,
};

struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v1(void)
{
	return &iommu_pm_hw_ops;
}
EXPORT_SYMBOL(iommu_pm_get_hw_ops_v1);

