/*
 * Copyright (C) 2012 Broadcom Corporation
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation version 2.
 *
 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
 * kind, whether express or implied; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/init.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/clockchips.h>
#include <linux/types.h>

#include <linux/io.h>
#include <asm/mach/time.h>

#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>


#define KONA_GPTIMER_STCS_OFFSET			0x00000000
#define KONA_GPTIMER_STCLO_OFFSET			0x00000004
#define KONA_GPTIMER_STCHI_OFFSET			0x00000008
#define KONA_GPTIMER_STCM0_OFFSET			0x0000000C

#define KONA_GPTIMER_STCS_TIMER_MATCH_SHIFT		0
#define KONA_GPTIMER_STCS_COMPARE_ENABLE_SHIFT		4

struct kona_bcm_timers {
	int tmr_irq;
	void __iomem *tmr_regs;
};

static struct kona_bcm_timers timers;

static u32 arch_timer_rate;

/*
 * We use the peripheral timers for system tick, the cpu global timer for
 * profile tick
 */
static void kona_timer_disable_and_clear(void __iomem *base)
{
	uint32_t reg;

	/*
	 * clear and disable interrupts
	 * We are using compare/match register 0 for our system interrupts
	 */
	reg = readl(base + KONA_GPTIMER_STCS_OFFSET);

	/* Clear compare (0) interrupt */
	reg |= 1 << KONA_GPTIMER_STCS_TIMER_MATCH_SHIFT;
	/* disable compare */
	reg &= ~(1 << KONA_GPTIMER_STCS_COMPARE_ENABLE_SHIFT);

	writel(reg, base + KONA_GPTIMER_STCS_OFFSET);

}

static void
kona_timer_get_counter(void *timer_base, uint32_t *msw, uint32_t *lsw)
{
	void __iomem *base = IOMEM(timer_base);
	int loop_limit = 4;

	/*
	 * Read 64-bit free running counter
	 * 1. Read hi-word
	 * 2. Read low-word
	 * 3. Read hi-word again
	 * 4.1
	 *      if new hi-word is not equal to previously read hi-word, then
	 *      start from #1
	 * 4.2
	 *      if new hi-word is equal to previously read hi-word then stop.
	 */

	while (--loop_limit) {
		*msw = readl(base + KONA_GPTIMER_STCHI_OFFSET);
		*lsw = readl(base + KONA_GPTIMER_STCLO_OFFSET);
		if (*msw == readl(base + KONA_GPTIMER_STCHI_OFFSET))
			break;
	}
	if (!loop_limit) {
		pr_err("bcm_kona_timer: getting counter failed.\n");
		pr_err(" Timer will be impacted\n");
	}

	return;
}

static const struct of_device_id bcm_timer_ids[] __initconst = {
	{.compatible = "bcm,kona-timer"},
	{},
};

static void __init kona_timers_init(struct device_node *node)
{
	u32 freq;

	if (!of_property_read_u32(node, "clock-frequency", &freq))
		arch_timer_rate = freq;
	else
		panic("clock-frequency not set in the .dts file");

	/* Setup IRQ numbers */
	timers.tmr_irq = irq_of_parse_and_map(node, 0);

	/* Setup IO addresses */
	timers.tmr_regs = of_iomap(node, 0);

	kona_timer_disable_and_clear(timers.tmr_regs);
}

static int kona_timer_set_next_event(unsigned long clc,
				  struct clock_event_device *unused)
{
	/*
	 * timer (0) is disabled by the timer interrupt already
	 * so, here we reload the next event value and re-enable
	 * the timer.
	 *
	 * This way, we are potentially losing the time between
	 * timer-interrupt->set_next_event. CPU local timers, when
	 * they come in should get rid of skew.
	 */

	uint32_t lsw, msw;
	uint32_t reg;

	kona_timer_get_counter(timers.tmr_regs, &msw, &lsw);

	/* Load the "next" event tick value */
	writel(lsw + clc, timers.tmr_regs + KONA_GPTIMER_STCM0_OFFSET);

	/* Enable compare */
	reg = readl(timers.tmr_regs + KONA_GPTIMER_STCS_OFFSET);
	reg |= (1 << KONA_GPTIMER_STCS_COMPARE_ENABLE_SHIFT);
	writel(reg, timers.tmr_regs + KONA_GPTIMER_STCS_OFFSET);

	return 0;
}

static void kona_timer_set_mode(enum clock_event_mode mode,
			     struct clock_event_device *unused)
{
	switch (mode) {
	case CLOCK_EVT_MODE_ONESHOT:
		/* by default mode is one shot don't do any thing */
		break;
	case CLOCK_EVT_MODE_UNUSED:
	case CLOCK_EVT_MODE_SHUTDOWN:
	default:
		kona_timer_disable_and_clear(timers.tmr_regs);
	}
}

static struct clock_event_device kona_clockevent_timer = {
	.name = "timer 1",
	.features = CLOCK_EVT_FEAT_ONESHOT,
	.set_next_event = kona_timer_set_next_event,
	.set_mode = kona_timer_set_mode
};

static void __init kona_timer_clockevents_init(void)
{
	kona_clockevent_timer.cpumask = cpumask_of(0);
	clockevents_config_and_register(&kona_clockevent_timer,
		arch_timer_rate, 6, 0xffffffff);
}

static irqreturn_t kona_timer_interrupt(int irq, void *dev_id)
{
	struct clock_event_device *evt = &kona_clockevent_timer;

	kona_timer_disable_and_clear(timers.tmr_regs);
	evt->event_handler(evt);
	return IRQ_HANDLED;
}

static struct irqaction kona_timer_irq = {
	.name = "Kona Timer Tick",
	.flags = IRQF_TIMER,
	.handler = kona_timer_interrupt,
};

static void __init kona_timer_init(struct device_node *node)
{
	kona_timers_init(node);
	kona_timer_clockevents_init();
	setup_irq(timers.tmr_irq, &kona_timer_irq);
	kona_timer_set_next_event((arch_timer_rate / HZ), NULL);
}

CLOCKSOURCE_OF_DECLARE(bcm_kona, "bcm,kona-timer", kona_timer_init);
