/*
 * Copyright (C) 2004-2007 Atmel Corporation
 *
 * Based on MIPS implementation arch/mips/kernel/time.c
 *   Copyright 2001 MontaVista Software Inc.
 *
 * 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/clocksource.h>
#include <linux/time.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kernel_stat.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/profile.h>
#include <linux/sysdev.h>
#include <linux/err.h>

#include <asm/div64.h>
#include <asm/sysreg.h>
#include <asm/io.h>
#include <asm/sections.h>

#include <asm/arch/time.h>

/* how many counter cycles in a jiffy? */
static u32 cycles_per_jiffy;

/* the count value for the next timer interrupt */
static u32 expirelo;

/* the I/O registers of the TC module */
static void __iomem *ioregs;

cycle_t read_cycle_count(void)
{
	return (cycle_t)timer_read(ioregs, 0, CV);
}

struct clocksource clocksource_avr32 = {
	.name		= "avr32",
	.rating		= 342,
	.read		= read_cycle_count,
	.mask		= CLOCKSOURCE_MASK(16),
	.shift		= 16,
	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
};

static void avr32_timer_ack(void)
{
	u16 count = expirelo;

	/* Ack this timer interrupt and set the next one, use a u16
	 * variable so it will wrap around correctly */
	count += cycles_per_jiffy;
	expirelo = count;
	timer_write(ioregs, 0, RC, expirelo);

	/* Check to see if we have missed any timer interrupts */
	count = timer_read(ioregs, 0, CV);
	if ((count - expirelo) < 0x7fff) {
		expirelo = count + cycles_per_jiffy;
		timer_write(ioregs, 0, RC, expirelo);
	}
}

u32 avr32_hpt_read(void)
{
	return timer_read(ioregs, 0, CV);
}

static int avr32_timer_calc_div_and_set_jiffies(struct clk *pclk)
{
	unsigned int cycles_max = (clocksource_avr32.mask + 1) / 2;
	unsigned int divs[] = { 4, 8, 16, 32 };
	int divs_size = sizeof(divs) / sizeof(*divs);
	int i = 0;
	unsigned long count_hz;
	unsigned long shift;
	unsigned long mult;
	int clock_div = -1;
	u64 tmp;

	shift = clocksource_avr32.shift;

	do {
		count_hz = clk_get_rate(pclk) / divs[i];
		mult = clocksource_hz2mult(count_hz, shift);
		clocksource_avr32.mult = mult;

		tmp = TICK_NSEC;
		tmp <<= shift;
		tmp += mult / 2;
		do_div(tmp, mult);

		cycles_per_jiffy = tmp;
	} while (cycles_per_jiffy > cycles_max && ++i < divs_size);

	clock_div = i + 1;

	if (clock_div > divs_size) {
		pr_debug("timer: could not calculate clock divider\n");
		return -EFAULT;
	}

	/* Set the clock divider */
	timer_write(ioregs, 0, CMR, TIMER_BF(CMR_TCCLKS, clock_div));

	return 0;
}

int avr32_hpt_init(unsigned int count)
{
	struct resource *regs;
	struct clk *pclk;
	int irq = -1;
	int ret = 0;

	ret = -ENXIO;

	irq = platform_get_irq(&at32_systc0_device, 0);
	if (irq < 0) {
		pr_debug("timer: could not get irq\n");
		goto out_error;
	}

	pclk = clk_get(&at32_systc0_device.dev, "pclk");
	if (IS_ERR(pclk)) {
		pr_debug("timer: could not get clk: %ld\n", PTR_ERR(pclk));
		goto out_error;
	}

	regs = platform_get_resource(&at32_systc0_device, IORESOURCE_MEM, 0);
	if (!regs) {
		pr_debug("timer: could not get resource\n");
		goto out_error_clk;
	}

	ioregs = ioremap(regs->start, regs->end - regs->start + 1);
	if (!ioregs) {
		pr_debug("timer: could not get ioregs\n");
		goto out_error_clk;
	}

	ret = avr32_timer_calc_div_and_set_jiffies(pclk);
	if (ret)
		goto out_error_io;

	ret = setup_irq(irq, &timer_irqaction);
	if (ret) {
		pr_debug("timer: could not request irq %d: %d\n",
				irq, ret);
		goto out_error_io;
	}

	expirelo = (timer_read(ioregs, 0, CV) / cycles_per_jiffy + 1)
		* cycles_per_jiffy;

	/* Enable clock and interrupts on RC compare */
	timer_write(ioregs, 0, CCR, TIMER_BIT(CCR_CLKEN));
	timer_write(ioregs, 0, IER, TIMER_BIT(IER_CPCS));
	/* Set cycles to first interrupt */
	timer_write(ioregs, 0,  RC, expirelo);

	printk(KERN_INFO "timer: AT32AP system timer/counter at 0x%p irq %d\n",
			ioregs, irq);

	return 0;

out_error_io:
	iounmap(ioregs);
out_error_clk:
	clk_put(pclk);
out_error:
	return ret;
}

int avr32_hpt_start(void)
{
	timer_write(ioregs, 0, CCR, TIMER_BIT(CCR_SWTRG));
	return 0;
}

irqreturn_t timer_interrupt(int irq, void *dev_id)
{
	unsigned int sr = timer_read(ioregs, 0, SR);

	if (sr & TIMER_BIT(SR_CPCS)) {
		/* ack timer interrupt and try to set next interrupt */
		avr32_timer_ack();

		/*
		 * Call the generic timer interrupt handler
		 */
		write_seqlock(&xtime_lock);
		do_timer(1);
		write_sequnlock(&xtime_lock);

		/*
		 * In UP mode, we call local_timer_interrupt() to do profiling
		 * and process accounting.
		 *
		 * SMP is not supported yet.
		 */
		local_timer_interrupt(irq, dev_id);

		return IRQ_HANDLED;
	}

	return IRQ_NONE;
}
