/*
 * Keystone broadcast clock-event
 *
 * Copyright 2013 Texas Instruments, Inc.
 *
 * Author: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
 *
 * 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.
 *
 */

#include <linux/clk.h>
#include <linux/clockchips.h>
#include <linux/clocksource.h>
#include <linux/interrupt.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>

#define TIMER_NAME			"timer-keystone"

/* Timer register offsets */
#define TIM12				0x10
#define TIM34				0x14
#define PRD12				0x18
#define PRD34				0x1c
#define TCR				0x20
#define TGCR				0x24
#define INTCTLSTAT			0x44

/* Timer register bitfields */
#define TCR_ENAMODE_MASK		0xC0
#define TCR_ENAMODE_ONESHOT_MASK	0x40
#define TCR_ENAMODE_PERIODIC_MASK	0x80

#define TGCR_TIM_UNRESET_MASK		0x03
#define INTCTLSTAT_ENINT_MASK		0x01

/**
 * struct keystone_timer: holds timer's data
 * @base: timer memory base address
 * @hz_period: cycles per HZ period
 * @event_dev: event device based on timer
 */
static struct keystone_timer {
	void __iomem *base;
	unsigned long hz_period;
	struct clock_event_device event_dev;
} timer;

static inline u32 keystone_timer_readl(unsigned long rg)
{
	return readl_relaxed(timer.base + rg);
}

static inline void keystone_timer_writel(u32 val, unsigned long rg)
{
	writel_relaxed(val, timer.base + rg);
}

/**
 * keystone_timer_barrier: write memory barrier
 * use explicit barrier to avoid using readl/writel non relaxed function
 * variants, because in our case non relaxed variants hide the true places
 * where barrier is needed.
 */
static inline void keystone_timer_barrier(void)
{
	__iowmb();
}

/**
 * keystone_timer_config: configures timer to work in oneshot/periodic modes.
 * @ mask: mask of the mode to configure
 * @ period: cycles number to configure for
 */
static int keystone_timer_config(u64 period, int mask)
{
	u32 tcr;
	u32 off;

	tcr = keystone_timer_readl(TCR);
	off = tcr & ~(TCR_ENAMODE_MASK);

	/* set enable mode */
	tcr |= mask;

	/* disable timer */
	keystone_timer_writel(off, TCR);
	/* here we have to be sure the timer has been disabled */
	keystone_timer_barrier();

	/* reset counter to zero, set new period */
	keystone_timer_writel(0, TIM12);
	keystone_timer_writel(0, TIM34);
	keystone_timer_writel(period & 0xffffffff, PRD12);
	keystone_timer_writel(period >> 32, PRD34);

	/*
	 * enable timer
	 * here we have to be sure that CNTLO, CNTHI, PRDLO, PRDHI registers
	 * have been written.
	 */
	keystone_timer_barrier();
	keystone_timer_writel(tcr, TCR);
	return 0;
}

static void keystone_timer_disable(void)
{
	u32 tcr;

	tcr = keystone_timer_readl(TCR);

	/* disable timer */
	tcr &= ~(TCR_ENAMODE_MASK);
	keystone_timer_writel(tcr, TCR);
}

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

	evt->event_handler(evt);
	return IRQ_HANDLED;
}

static int keystone_set_next_event(unsigned long cycles,
				  struct clock_event_device *evt)
{
	return keystone_timer_config(cycles, TCR_ENAMODE_ONESHOT_MASK);
}

static int keystone_shutdown(struct clock_event_device *evt)
{
	keystone_timer_disable();
	return 0;
}

static int keystone_set_periodic(struct clock_event_device *evt)
{
	keystone_timer_config(timer.hz_period, TCR_ENAMODE_PERIODIC_MASK);
	return 0;
}

static void __init keystone_timer_init(struct device_node *np)
{
	struct clock_event_device *event_dev = &timer.event_dev;
	unsigned long rate;
	struct clk *clk;
	int irq, error;

	irq  = irq_of_parse_and_map(np, 0);
	if (irq == NO_IRQ) {
		pr_err("%s: failed to map interrupts\n", __func__);
		return;
	}

	timer.base = of_iomap(np, 0);
	if (!timer.base) {
		pr_err("%s: failed to map registers\n", __func__);
		return;
	}

	clk = of_clk_get(np, 0);
	if (IS_ERR(clk)) {
		pr_err("%s: failed to get clock\n", __func__);
		iounmap(timer.base);
		return;
	}

	error = clk_prepare_enable(clk);
	if (error) {
		pr_err("%s: failed to enable clock\n", __func__);
		goto err;
	}

	rate = clk_get_rate(clk);

	/* disable, use internal clock source */
	keystone_timer_writel(0, TCR);
	/* here we have to be sure the timer has been disabled */
	keystone_timer_barrier();

	/* reset timer as 64-bit, no pre-scaler, plus features are disabled */
	keystone_timer_writel(0, TGCR);

	/* unreset timer */
	keystone_timer_writel(TGCR_TIM_UNRESET_MASK, TGCR);

	/* init counter to zero */
	keystone_timer_writel(0, TIM12);
	keystone_timer_writel(0, TIM34);

	timer.hz_period = DIV_ROUND_UP(rate, HZ);

	/* enable timer interrupts */
	keystone_timer_writel(INTCTLSTAT_ENINT_MASK, INTCTLSTAT);

	error = request_irq(irq, keystone_timer_interrupt, IRQF_TIMER,
			    TIMER_NAME, event_dev);
	if (error) {
		pr_err("%s: failed to setup irq\n", __func__);
		goto err;
	}

	/* setup clockevent */
	event_dev->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
	event_dev->set_next_event = keystone_set_next_event;
	event_dev->set_state_shutdown = keystone_shutdown;
	event_dev->set_state_periodic = keystone_set_periodic;
	event_dev->set_state_oneshot = keystone_shutdown;
	event_dev->cpumask = cpu_all_mask;
	event_dev->owner = THIS_MODULE;
	event_dev->name = TIMER_NAME;
	event_dev->irq = irq;

	clockevents_config_and_register(event_dev, rate, 1, ULONG_MAX);

	pr_info("keystone timer clock @%lu Hz\n", rate);
	return;
err:
	clk_put(clk);
	iounmap(timer.base);
}

CLOCKSOURCE_OF_DECLARE(keystone_timer, "ti,keystone-timer",
					keystone_timer_init);
