/*
 * 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 int __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) {
		pr_err("%s: failed to map interrupts\n", __func__);
		return -EINVAL;
	}

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

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

	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_possible_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 0;
err:
	clk_put(clk);
	iounmap(timer.base);
	return error;
}

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