/*
 * Copyright (C) 2005-2013 Imagination Technologies Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 * Support for Meta per-thread timers.
 *
 * Meta hardware threads have 2 timers. The background timer (TXTIMER) is used
 * as a free-running time base (hz clocksource), and the interrupt timer
 * (TXTIMERI) is used for the timer interrupt (clock event). Both counters
 * traditionally count at approximately 1MHz.
 */

#include <clocksource/metag_generic.h>
#include <linux/cpu.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/interrupt.h>

#include <asm/clock.h>
#include <asm/hwthread.h>
#include <asm/core_reg.h>
#include <asm/metag_mem.h>
#include <asm/tbx.h>

#define HARDWARE_FREQ		1000000	/* 1MHz */
#define HARDWARE_DIV		1	/* divide by 1 = 1MHz clock */
#define HARDWARE_TO_NS_SHIFT	10	/* convert ticks to ns */

static unsigned int hwtimer_freq = HARDWARE_FREQ;
static DEFINE_PER_CPU(struct clock_event_device, local_clockevent);
static DEFINE_PER_CPU(char [11], local_clockevent_name);

static int metag_timer_set_next_event(unsigned long delta,
				      struct clock_event_device *dev)
{
	__core_reg_set(TXTIMERI, -delta);
	return 0;
}

static u64 metag_clocksource_read(struct clocksource *cs)
{
	return __core_reg_get(TXTIMER);
}

static struct clocksource clocksource_metag = {
	.name = "META",
	.rating = 200,
	.mask = CLOCKSOURCE_MASK(32),
	.read = metag_clocksource_read,
	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};

static irqreturn_t metag_timer_interrupt(int irq, void *dummy)
{
	struct clock_event_device *evt = this_cpu_ptr(&local_clockevent);

	evt->event_handler(evt);

	return IRQ_HANDLED;
}

static struct irqaction metag_timer_irq = {
	.name = "META core timer",
	.handler = metag_timer_interrupt,
	.flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_PERCPU,
};

unsigned long long sched_clock(void)
{
	unsigned long long ticks = __core_reg_get(TXTIMER);
	return ticks << HARDWARE_TO_NS_SHIFT;
}

static int arch_timer_starting_cpu(unsigned int cpu)
{
	unsigned int txdivtime;
	struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
	char *name = per_cpu(local_clockevent_name, cpu);

	txdivtime = __core_reg_get(TXDIVTIME);

	txdivtime &= ~TXDIVTIME_DIV_BITS;
	txdivtime |= (HARDWARE_DIV & TXDIVTIME_DIV_BITS);

	__core_reg_set(TXDIVTIME, txdivtime);

	sprintf(name, "META %d", cpu);
	clk->name = name;
	clk->features = CLOCK_EVT_FEAT_ONESHOT,

	clk->rating = 200,
	clk->shift = 12,
	clk->irq = tbisig_map(TBID_SIGNUM_TRT),
	clk->set_next_event = metag_timer_set_next_event,

	clk->mult = div_sc(hwtimer_freq, NSEC_PER_SEC, clk->shift);
	clk->max_delta_ns = clockevent_delta2ns(0x7fffffff, clk);
	clk->max_delta_ticks = 0x7fffffff;
	clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
	clk->min_delta_ticks = 0xf;
	clk->cpumask = cpumask_of(cpu);

	clockevents_register_device(clk);

	/*
	 * For all non-boot CPUs we need to synchronize our free
	 * running clock (TXTIMER) with the boot CPU's clock.
	 *
	 * While this won't be accurate, it should be close enough.
	 */
	if (cpu) {
		unsigned int thread0 = cpu_2_hwthread_id[0];
		unsigned long val;

		val = core_reg_read(TXUCT_ID, TXTIMER_REGNUM, thread0);
		__core_reg_set(TXTIMER, val);
	}
	return 0;
}

int __init metag_generic_timer_init(void)
{
	/*
	 * On Meta 2 SoCs, the actual frequency of the timer is based on the
	 * Meta core clock speed divided by an integer, so it is only
	 * approximately 1MHz. Calculating the real frequency here drastically
	 * reduces clock skew on these SoCs.
	 */
#ifdef CONFIG_METAG_META21
	hwtimer_freq = get_coreclock() / (metag_in32(EXPAND_TIMER_DIV) + 1);
#endif
	pr_info("Timer frequency: %u Hz\n", hwtimer_freq);

	clocksource_register_hz(&clocksource_metag, hwtimer_freq);

	setup_irq(tbisig_map(TBID_SIGNUM_TRT), &metag_timer_irq);

	/* Hook cpu boot to configure the CPU's timers */
	return cpuhp_setup_state(CPUHP_AP_METAG_TIMER_STARTING,
				 "clockevents/metag:starting",
				 arch_timer_starting_cpu, NULL);
}
