/*
 * 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 <linux/mc146818rtc.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_mips_get_time = it8172_rtc_get_time;
	rtc_mips_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);
}
