/*
 * QEMU ETRAX Timers
 *
 * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include <stdio.h>
#include <sys/time.h>
#include "hw.h"
#include "sysemu.h"
#include "qemu-timer.h"

#define D(x)

#define RW_TMR0_DIV   0x00
#define R_TMR0_DATA   0x04
#define RW_TMR0_CTRL  0x08
#define RW_TMR1_DIV   0x10
#define R_TMR1_DATA   0x14
#define RW_TMR1_CTRL  0x18
#define R_TIME        0x38
#define RW_WD_CTRL    0x40
#define R_WD_STAT     0x44
#define RW_INTR_MASK  0x48
#define RW_ACK_INTR   0x4c
#define R_INTR        0x50
#define R_MASKED_INTR 0x54

struct fs_timer_t {
	CPUState *env;
	qemu_irq *irq;
	target_phys_addr_t base;

	QEMUBH *bh_t0;
	QEMUBH *bh_t1;
	QEMUBH *bh_wd;
	ptimer_state *ptimer_t0;
	ptimer_state *ptimer_t1;
	ptimer_state *ptimer_wd;
	struct timeval last;

	/* Control registers.  */
	uint32_t rw_tmr0_div;
	uint32_t r_tmr0_data;
	uint32_t rw_tmr0_ctrl;

	uint32_t rw_tmr1_div;
	uint32_t r_tmr1_data;
	uint32_t rw_tmr1_ctrl;

	uint32_t rw_wd_ctrl;

	uint32_t rw_intr_mask;
	uint32_t rw_ack_intr;
	uint32_t r_intr;
	uint32_t r_masked_intr;
};

static uint32_t timer_rinvalid (void *opaque, target_phys_addr_t addr)
{
	struct fs_timer_t *t = opaque;
	CPUState *env = t->env;
	cpu_abort(env, "Unsupported short access. reg=%x pc=%x.\n", 
		  addr, env->pc);
	return 0;
}

static uint32_t timer_readl (void *opaque, target_phys_addr_t addr)
{
	struct fs_timer_t *t = opaque;
	D(CPUState *env = t->env);
	uint32_t r = 0;

	/* Make addr relative to this instances base.  */
	addr -= t->base;
	switch (addr) {
	case R_TMR0_DATA:
		break;
	case R_TMR1_DATA:
		D(printf ("R_TMR1_DATA\n"));
		break;
	case R_TIME:
		r = qemu_get_clock(vm_clock) * 10;
		break;
	case RW_INTR_MASK:
		r = t->rw_intr_mask;
		break;
	case R_MASKED_INTR:
		r = t->r_intr & t->rw_intr_mask;
		break;
	default:
		D(printf ("%s %x p=%x\n", __func__, addr, env->pc));
		break;
	}
	return r;
}

static void
timer_winvalid (void *opaque, target_phys_addr_t addr, uint32_t value)
{
	struct fs_timer_t *t = opaque;
	CPUState *env = t->env;
	cpu_abort(env, "Unsupported short access. reg=%x pc=%x.\n", 
		  addr, env->pc);
}

#define TIMER_SLOWDOWN 1
static void update_ctrl(struct fs_timer_t *t, int tnum)
{
	unsigned int op;
	unsigned int freq;
	unsigned int freq_hz;
	unsigned int div;
	uint32_t ctrl;
	ptimer_state *timer;

	if (tnum == 0) {
		ctrl = t->rw_tmr0_ctrl;
		div = t->rw_tmr0_div;
		timer = t->ptimer_t0;
	} else {
		ctrl = t->rw_tmr1_ctrl;
		div = t->rw_tmr1_div;
		timer = t->ptimer_t1;
	}


	op = ctrl & 3;
	freq = ctrl >> 2;
	freq_hz = 32000000;

	switch (freq)
	{
	case 0:
	case 1:
		D(printf ("extern or disabled timer clock?\n"));
		break;
	case 4: freq_hz =  29493000; break;
	case 5: freq_hz =  32000000; break;
	case 6: freq_hz =  32768000; break;
	case 7: freq_hz = 100001000; break;
	default:
		abort();
		break;
	}

	D(printf ("freq_hz=%d div=%d\n", freq_hz, div));
	div = div * TIMER_SLOWDOWN;
	div >>= 15;
	freq_hz >>= 15;
	ptimer_set_freq(timer, freq_hz);
	ptimer_set_limit(timer, div, 0);

	switch (op)
	{
		case 0:
			/* Load.  */
			ptimer_set_limit(timer, div, 1);
			break;
		case 1:
			/* Hold.  */
			ptimer_stop(timer);
			break;
		case 2:
			/* Run.  */
			ptimer_run(timer, 0);
			break;
		default:
			abort();
			break;
	}
}

static void timer_update_irq(struct fs_timer_t *t)
{
	t->r_intr &= ~(t->rw_ack_intr);
	t->r_masked_intr = t->r_intr & t->rw_intr_mask;

	D(printf("%s: masked_intr=%x\n", __func__, t->r_masked_intr));
	if (t->r_masked_intr)
		qemu_irq_raise(t->irq[0]);
	else
		qemu_irq_lower(t->irq[0]);
}

static void timer0_hit(void *opaque)
{
	struct fs_timer_t *t = opaque;
	t->r_intr |= 1;
	timer_update_irq(t);
}

static void timer1_hit(void *opaque)
{
	struct fs_timer_t *t = opaque;
	t->r_intr |= 2;
	timer_update_irq(t);
}

static void watchdog_hit(void *opaque)
{
	qemu_system_reset_request();
}

static inline void timer_watchdog_update(struct fs_timer_t *t, uint32_t value)
{
	unsigned int wd_en = t->rw_wd_ctrl & (1 << 8);
	unsigned int wd_key = t->rw_wd_ctrl >> 9;
	unsigned int wd_cnt = t->rw_wd_ctrl & 511;
	unsigned int new_key = value >> 9 & ((1 << 7) - 1);
	unsigned int new_cmd = (value >> 8) & 1;

	/* If the watchdog is enabled, they written key must match the
	   complement of the previous.  */
	wd_key = ~wd_key & ((1 << 7) - 1);

	if (wd_en && wd_key != new_key)
		return;

	D(printf("en=%d new_key=%x oldkey=%x cmd=%d cnt=%d\n", 
		 wd_en, new_key, wd_key, new_cmd, wd_cnt));

	ptimer_set_freq(t->ptimer_wd, 760);
	if (wd_cnt == 0)
		wd_cnt = 256;
	ptimer_set_count(t->ptimer_wd, wd_cnt);
	if (new_cmd)
		ptimer_run(t->ptimer_wd, 1);
	else
		ptimer_stop(t->ptimer_wd);

	t->rw_wd_ctrl = value;
}

static void
timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
{
	struct fs_timer_t *t = opaque;
	CPUState *env = t->env;

	/* Make addr relative to this instances base.  */
	addr -= t->base;
	switch (addr)
	{
		case RW_TMR0_DIV:
			t->rw_tmr0_div = value;
			break;
		case RW_TMR0_CTRL:
			D(printf ("RW_TMR0_CTRL=%x\n", value));
			t->rw_tmr0_ctrl = value;
			update_ctrl(t, 0);
			break;
		case RW_TMR1_DIV:
			t->rw_tmr1_div = value;
			break;
		case RW_TMR1_CTRL:
			D(printf ("RW_TMR1_CTRL=%x\n", value));
			t->rw_tmr1_ctrl = value;
			update_ctrl(t, 1);
			break;
		case RW_INTR_MASK:
			D(printf ("RW_INTR_MASK=%x\n", value));
			t->rw_intr_mask = value;
			timer_update_irq(t);
			break;
		case RW_WD_CTRL:
			timer_watchdog_update(t, value);
			break;
		case RW_ACK_INTR:
			t->rw_ack_intr = value;
			timer_update_irq(t);
			t->rw_ack_intr = 0;
			break;
		default:
			printf ("%s %x %x pc=%x\n",
				__func__, addr, value, env->pc);
			break;
	}
}

static CPUReadMemoryFunc *timer_read[] = {
	&timer_rinvalid,
	&timer_rinvalid,
	&timer_readl,
};

static CPUWriteMemoryFunc *timer_write[] = {
	&timer_winvalid,
	&timer_winvalid,
	&timer_writel,
};

static void etraxfs_timer_reset(void *opaque)
{
	struct fs_timer_t *t = opaque;

	ptimer_stop(t->ptimer_t0);
	ptimer_stop(t->ptimer_t1);
	ptimer_stop(t->ptimer_wd);
	t->rw_wd_ctrl = 0;
	t->r_intr = 0;
	t->rw_intr_mask = 0;
	qemu_irq_lower(t->irq[0]);
}

void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, 
			target_phys_addr_t base)
{
	static struct fs_timer_t *t;
	int timer_regs;

	t = qemu_mallocz(sizeof *t);
	if (!t)
		return;

	t->bh_t0 = qemu_bh_new(timer0_hit, t);
	t->bh_t1 = qemu_bh_new(timer1_hit, t);
	t->bh_wd = qemu_bh_new(watchdog_hit, t);
	t->ptimer_t0 = ptimer_init(t->bh_t0);
	t->ptimer_t1 = ptimer_init(t->bh_t1);
	t->ptimer_wd = ptimer_init(t->bh_wd);
	t->irq = irqs;
	t->env = env;
	t->base = base;

	timer_regs = cpu_register_io_memory(0, timer_read, timer_write, t);
	cpu_register_physical_memory (base, 0x5c, timer_regs);

	qemu_register_reset(etraxfs_timer_reset, t);
}
