/*
 * Carsten Langgaard, carstenl@mips.com
 * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
 *
 * Copyright (C) 2003 MontaVista Software Inc.
 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
 *
 * ########################################################################
 *
 *  This program is free software; you can distribute it and/or modify it
 *  under the terms of the GNU General Public License (Version 2) as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 *  for more details.
 *
 *  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.,
 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 *
 * ########################################################################
 *
 * Setting up the clock on the MIPS boards.
 */
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/spinlock.h>

#include <asm/time.h>
#include <asm/mipsregs.h>
#include <asm/ptrace.h>
#include <asm/it8172/it8172.h>
#include <asm/it8172/it8172_int.h>
#include <asm/debug.h>

#define IT8172_RTC_ADR_REG  (IT8172_PCI_IO_BASE + IT_RTC_BASE)
#define IT8172_RTC_DAT_REG  (IT8172_RTC_ADR_REG + 1)
#define IT8172_RTC_CENTURY_REG  (IT8172_PCI_IO_BASE + IT_RTC_CENTURY)

static volatile char *rtc_adr_reg = (char*)KSEG1ADDR(IT8172_RTC_ADR_REG);
static volatile char *rtc_dat_reg = (char*)KSEG1ADDR(IT8172_RTC_DAT_REG);
static volatile char *rtc_century_reg = (char*)KSEG1ADDR(IT8172_RTC_CENTURY_REG);

unsigned char it8172_rtc_read_data(unsigned long addr)
{
	unsigned char retval;

	*rtc_adr_reg = addr;
	retval =  *rtc_dat_reg;
	return retval;
}

void it8172_rtc_write_data(unsigned char data, unsigned long addr)
{
	*rtc_adr_reg = addr;
	*rtc_dat_reg = data;
}

#undef 	CMOS_READ
#undef 	CMOS_WRITE
#define	CMOS_READ(addr)			it8172_rtc_read_data(addr)
#define CMOS_WRITE(data, addr) 		it8172_rtc_write_data(data, addr)

static unsigned char saved_control;	/* remember rtc control reg */
static inline int rtc_24h(void) { return saved_control & RTC_24H; }
static inline int rtc_dm_binary(void) { return saved_control & RTC_DM_BINARY; }

static inline unsigned char
bin_to_hw(unsigned char c)
{
	if (rtc_dm_binary())
		return c;
	else
		return ((c/10) << 4) + (c%10);
}

static inline unsigned char
hw_to_bin(unsigned char c)
{
	if (rtc_dm_binary())
		return c;
	else
		return (c>>4)*10 + (c &0xf);
}

/* 0x80 bit indicates pm in 12-hour format */
static inline unsigned char
hour_bin_to_hw(unsigned char c)
{
	if (rtc_24h())
		return bin_to_hw(c);
	if (c >= 12)
		return 0x80 | bin_to_hw((c==12)?12:c-12);  /* 12 is 12pm */
	else
		return bin_to_hw((c==0)?12:c);	/* 0 is 12 AM, not 0 am */
}

static inline unsigned char
hour_hw_to_bin(unsigned char c)
{
	unsigned char tmp = hw_to_bin(c&0x3f);
	if (rtc_24h())
		return tmp;
	if (c & 0x80)
		return (tmp==12)?12:tmp+12;  	/* 12pm is 12, not 24 */
	else
		return (tmp==12)?0:tmp;		/* 12am is 0 */
}

static unsigned long r4k_offset; /* Amount to increment compare reg each time */
static unsigned long r4k_cur;    /* What counter should be at next timer irq */
extern unsigned int mips_hpt_frequency;

/*
 * Figure out the r4k offset, the amount to increment the compare
 * register for each time tick.
 * Use the RTC to calculate offset.
 */
static unsigned long __init cal_r4koff(void)
{
	unsigned int flags;

	local_irq_save(flags);

	/* Start counter exactly on falling edge of update flag */
	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));

	/* Start r4k counter. */
	write_c0_count(0);

	/* Read counter exactly on falling edge of update flag */
	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));

	mips_hpt_frequency = read_c0_count();

	/* restore interrupts */
	local_irq_restore(flags);

	return (mips_hpt_frequency / HZ);
}

static unsigned long
it8172_rtc_get_time(void)
{
	unsigned int year, mon, day, hour, min, sec;
	unsigned int flags;

	/* avoid update-in-progress. */
	for (;;) {
		local_irq_save(flags);
		if (! (CMOS_READ(RTC_REG_A) & RTC_UIP))
			break;
		/* don't hold intr closed all the time */
		local_irq_restore(flags);
	}

	/* Read regs. */
	sec = hw_to_bin(CMOS_READ(RTC_SECONDS));
	min = hw_to_bin(CMOS_READ(RTC_MINUTES));
	hour = hour_hw_to_bin(CMOS_READ(RTC_HOURS));
	day = hw_to_bin(CMOS_READ(RTC_DAY_OF_MONTH));
	mon = hw_to_bin(CMOS_READ(RTC_MONTH));
	year = hw_to_bin(CMOS_READ(RTC_YEAR)) +
		hw_to_bin(*rtc_century_reg) * 100;

	/* restore interrupts */
	local_irq_restore(flags);

	return mktime(year, mon, day, hour, min, sec);
}

static int
it8172_rtc_set_time(unsigned long t)
{
	struct rtc_time tm;
	unsigned int flags;

	/* convert */
	to_tm(t, &tm);

	/* avoid update-in-progress. */
	for (;;) {
		local_irq_save(flags);
		if (! (CMOS_READ(RTC_REG_A) & RTC_UIP))
			break;
		/* don't hold intr closed all the time */
		local_irq_restore(flags);
	}

	*rtc_century_reg = bin_to_hw(tm.tm_year/100);
	CMOS_WRITE(bin_to_hw(tm.tm_sec), RTC_SECONDS);
	CMOS_WRITE(bin_to_hw(tm.tm_min), RTC_MINUTES);
	CMOS_WRITE(hour_bin_to_hw(tm.tm_hour), RTC_HOURS);
	CMOS_WRITE(bin_to_hw(tm.tm_mday), RTC_DAY_OF_MONTH);
	CMOS_WRITE(bin_to_hw(tm.tm_mon+1), RTC_MONTH);	/* tm_mon starts from 0 */
	CMOS_WRITE(bin_to_hw(tm.tm_year%100), RTC_YEAR);

	/* restore interrupts */
	local_irq_restore(flags);

	return 0;
}

void __init it8172_time_init(void)
{
        unsigned int est_freq, flags;

	local_irq_save(flags);

	saved_control = CMOS_READ(RTC_CONTROL);

	printk("calculating r4koff... ");
	r4k_offset = cal_r4koff();
	printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);

	est_freq = 2*r4k_offset*HZ;
	est_freq += 5000;    /* round */
	est_freq -= est_freq%10000;
	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
	       (est_freq%1000000)*100/1000000);

	local_irq_restore(flags);

	rtc_get_time = it8172_rtc_get_time;
	rtc_set_time = it8172_rtc_set_time;
}

#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
void __init it8172_timer_setup(struct irqaction *irq)
{
	puts("timer_setup\n");
	put32(NR_IRQS);
	puts("");
        /* we are using the cpu counter for timer interrupts */
	setup_irq(MIPS_CPU_TIMER_IRQ, irq);

        /* to generate the first timer interrupt */
	r4k_cur = (read_c0_count() + r4k_offset);
	write_c0_compare(r4k_cur);
	set_c0_status(ALLINTS);
}
