/*
 * linux/arch/arm/plat-omap/dmtimer.c
 *
 * OMAP Dual-Mode Timers
 *
 * Copyright (C) 2005 Nokia Corporation
 * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com>
 *
 * 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; either version 2 of the License, or (at your
 * option) any later version.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * You should have received a copy of the  GNU General Public License along
 * with this program; if not, write  to the Free Software Foundation, Inc.,
 * 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/arch/dmtimer.h>
#include <asm/io.h>
#include <asm/arch/irqs.h>
#include <linux/spinlock.h>
#include <linux/list.h>

#define OMAP_TIMER_COUNT		8

#define OMAP_TIMER_ID_REG		0x00
#define OMAP_TIMER_OCP_CFG_REG		0x10
#define OMAP_TIMER_SYS_STAT_REG		0x14
#define OMAP_TIMER_STAT_REG		0x18
#define OMAP_TIMER_INT_EN_REG		0x1c
#define OMAP_TIMER_WAKEUP_EN_REG	0x20
#define OMAP_TIMER_CTRL_REG		0x24
#define OMAP_TIMER_COUNTER_REG		0x28
#define OMAP_TIMER_LOAD_REG		0x2c
#define OMAP_TIMER_TRIGGER_REG		0x30
#define OMAP_TIMER_WRITE_PEND_REG 	0x34
#define OMAP_TIMER_MATCH_REG		0x38
#define OMAP_TIMER_CAPTURE_REG		0x3c
#define OMAP_TIMER_IF_CTRL_REG		0x40


static struct dmtimer_info_struct {
	struct list_head	unused_timers;
	struct list_head	reserved_timers;
} dm_timer_info;

static struct omap_dm_timer dm_timers[] = {
	{ .base=0xfffb1400, .irq=INT_1610_GPTIMER1 },
	{ .base=0xfffb1c00, .irq=INT_1610_GPTIMER2 },
	{ .base=0xfffb2400, .irq=INT_1610_GPTIMER3 },
	{ .base=0xfffb2c00, .irq=INT_1610_GPTIMER4 },
	{ .base=0xfffb3400, .irq=INT_1610_GPTIMER5 },
	{ .base=0xfffb3c00, .irq=INT_1610_GPTIMER6 },
	{ .base=0xfffb4400, .irq=INT_1610_GPTIMER7 },
	{ .base=0xfffb4c00, .irq=INT_1610_GPTIMER8 },
	{ .base=0x0 },
};


static spinlock_t dm_timer_lock;


inline void omap_dm_timer_write_reg(struct omap_dm_timer *timer, int reg, u32 value)
{
	omap_writel(value, timer->base + reg);
	while (omap_dm_timer_read_reg(timer, OMAP_TIMER_WRITE_PEND_REG))
		;
}

u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, int reg)
{
	return omap_readl(timer->base + reg);
}

int omap_dm_timers_active(void)
{
	struct omap_dm_timer *timer;

	for (timer = &dm_timers[0]; timer->base; ++timer)
		if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
		    OMAP_TIMER_CTRL_ST)
			return 1;

	return 0;
}


/**
 * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR
 * @inputmask: current value of idlect mask
 */
__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
{
	int n;

	/* If ARMXOR cannot be idled this function call is unnecessary */
	if (!(inputmask & (1 << 1)))
		return inputmask;

	/* If any active timer is using ARMXOR return modified mask */
	for (n = 0; dm_timers[n].base; ++n)
		if (omap_dm_timer_read_reg(&dm_timers[n], OMAP_TIMER_CTRL_REG)&
		    OMAP_TIMER_CTRL_ST) {
			if (((omap_readl(MOD_CONF_CTRL_1)>>(n*2)) & 0x03) == 0)
				inputmask &= ~(1 << 1);
			else
				inputmask &= ~(1 << 2);
		}

	return inputmask;
}


void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
{
	int n = (timer - dm_timers) << 1;
	u32 l;

	l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
	l |= source << n;
	omap_writel(l, MOD_CONF_CTRL_1);
}


static void omap_dm_timer_reset(struct omap_dm_timer *timer)
{
	/* Reset and set posted mode */
	omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
	omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, 0x02);

	omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_ARMXOR);
}



struct omap_dm_timer * omap_dm_timer_request(void)
{
	struct omap_dm_timer *timer = NULL;
	unsigned long flags;

	spin_lock_irqsave(&dm_timer_lock, flags);
	if (!list_empty(&dm_timer_info.unused_timers)) {
		timer = (struct omap_dm_timer *)
				dm_timer_info.unused_timers.next;
		list_move_tail((struct list_head *)timer,
				&dm_timer_info.reserved_timers);
	}
	spin_unlock_irqrestore(&dm_timer_lock, flags);

	return timer;
}


void omap_dm_timer_free(struct omap_dm_timer *timer)
{
	unsigned long flags;

	omap_dm_timer_reset(timer);

	spin_lock_irqsave(&dm_timer_lock, flags);
	list_move_tail((struct list_head *)timer, &dm_timer_info.unused_timers);
	spin_unlock_irqrestore(&dm_timer_lock, flags);
}

void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
				unsigned int value)
{
	omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value);
}

unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
{
	return omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);
}

void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
{
	omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value);
}

void omap_dm_timer_enable_autoreload(struct omap_dm_timer *timer)
{
	u32 l;
	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
	l |= OMAP_TIMER_CTRL_AR;
	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}

void omap_dm_timer_trigger(struct omap_dm_timer *timer)
{
	omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 1);
}

void omap_dm_timer_set_trigger(struct omap_dm_timer *timer, unsigned int value)
{
	u32 l;

	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
	l |= value & 0x3;
	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}

void omap_dm_timer_start(struct omap_dm_timer *timer)
{
	u32 l;

	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
	l |= OMAP_TIMER_CTRL_ST;
	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}

void omap_dm_timer_stop(struct omap_dm_timer *timer)
{
	u32 l;

	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
	l &= ~0x1;
	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}

unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
{
	return omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
}

void omap_dm_timer_reset_counter(struct omap_dm_timer *timer)
{
	omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, 0);
}

void omap_dm_timer_set_load(struct omap_dm_timer *timer, unsigned int load)
{
	omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
}

void omap_dm_timer_set_match(struct omap_dm_timer *timer, unsigned int match)
{
	omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
}

void omap_dm_timer_enable_compare(struct omap_dm_timer *timer)
{
	u32 l;

	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
	l |= OMAP_TIMER_CTRL_CE;
	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}


static inline void __dm_timer_init(void)
{
	struct omap_dm_timer *timer;

	spin_lock_init(&dm_timer_lock);
	INIT_LIST_HEAD(&dm_timer_info.unused_timers);
	INIT_LIST_HEAD(&dm_timer_info.reserved_timers);

	timer = &dm_timers[0];
	while (timer->base) {
		list_add_tail((struct list_head *)timer, &dm_timer_info.unused_timers);
		omap_dm_timer_reset(timer);
		timer++;
	}
}

static int __init omap_dm_timer_init(void)
{
	if (cpu_is_omap16xx())
		__dm_timer_init();
	return 0;
}

arch_initcall(omap_dm_timer_init);
