/*
 *  linux/arch/i386/kernel/time_hpet.c
 *  This code largely copied from arch/x86_64/kernel/time.c
 *  See that file for credits.
 *
 *  2003-06-30    Venkatesh Pallipadi - Additional changes for HPET support
 */

#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/smp.h>

#include <asm/timer.h>
#include <asm/fixmap.h>
#include <asm/apic.h>

#include <linux/timex.h>

#include <asm/hpet.h>
#include <linux/hpet.h>

static unsigned long hpet_period;	/* fsecs / HPET clock */
unsigned long hpet_tick;		/* hpet clks count per tick */
unsigned long hpet_address;		/* hpet memory map physical address */
int hpet_use_timer;

static int use_hpet; 		/* can be used for runtime check of hpet */
static int boot_hpet_disable; 	/* boottime override for HPET timer */
static void __iomem * hpet_virt_address;	/* hpet kernel virtual address */

#define FSEC_TO_USEC (1000000000UL)

int hpet_readl(unsigned long a)
{
	return readl(hpet_virt_address + a);
}

static void hpet_writel(unsigned long d, unsigned long a)
{
	writel(d, hpet_virt_address + a);
}

#ifdef CONFIG_X86_LOCAL_APIC
/*
 * HPET counters dont wrap around on every tick. They just change the
 * comparator value and continue. Next tick can be caught by checking
 * for a change in the comparator value. Used in apic.c.
 */
static void __devinit wait_hpet_tick(void)
{
	unsigned int start_cmp_val, end_cmp_val;

	start_cmp_val = hpet_readl(HPET_T0_CMP);
	do {
		end_cmp_val = hpet_readl(HPET_T0_CMP);
	} while (start_cmp_val == end_cmp_val);
}
#endif

static int hpet_timer_stop_set_go(unsigned long tick)
{
	unsigned int cfg;

	/*
	 * Stop the timers and reset the main counter.
	 */
	cfg = hpet_readl(HPET_CFG);
	cfg &= ~HPET_CFG_ENABLE;
	hpet_writel(cfg, HPET_CFG);
	hpet_writel(0, HPET_COUNTER);
	hpet_writel(0, HPET_COUNTER + 4);

	if (hpet_use_timer) {
		/*
		 * Set up timer 0, as periodic with first interrupt to happen at
		 * hpet_tick, and period also hpet_tick.
		 */
		cfg = hpet_readl(HPET_T0_CFG);
		cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
		       HPET_TN_SETVAL | HPET_TN_32BIT;
		hpet_writel(cfg, HPET_T0_CFG);

		/*
		 * The first write after writing TN_SETVAL to the config register sets
		 * the counter value, the second write sets the threshold.
		 */
		hpet_writel(tick, HPET_T0_CMP);
		hpet_writel(tick, HPET_T0_CMP);
	}
	/*
 	 * Go!
 	 */
	cfg = hpet_readl(HPET_CFG);
	if (hpet_use_timer)
		cfg |= HPET_CFG_LEGACY;
	cfg |= HPET_CFG_ENABLE;
	hpet_writel(cfg, HPET_CFG);

	return 0;
}

/*
 * Check whether HPET was found by ACPI boot parse. If yes setup HPET
 * counter 0 for kernel base timer.
 */
int __init hpet_enable(void)
{
	unsigned int id;
	unsigned long tick_fsec_low, tick_fsec_high; /* tick in femto sec */
	unsigned long hpet_tick_rem;

	if (boot_hpet_disable)
		return -1;

	if (!hpet_address) {
		return -1;
	}
	hpet_virt_address = ioremap_nocache(hpet_address, HPET_MMAP_SIZE);
	/*
	 * Read the period, compute tick and quotient.
	 */
	id = hpet_readl(HPET_ID);

	/*
	 * We are checking for value '1' or more in number field if
	 * CONFIG_HPET_EMULATE_RTC is set because we will need an
	 * additional timer for RTC emulation.
	 * However, we can do with one timer otherwise using the
	 * the single HPET timer for system time.
	 */
#ifdef CONFIG_HPET_EMULATE_RTC
	if (!(id & HPET_ID_NUMBER))
		return -1;
#endif


	hpet_period = hpet_readl(HPET_PERIOD);
	if ((hpet_period < HPET_MIN_PERIOD) || (hpet_period > HPET_MAX_PERIOD))
		return -1;

	/*
	 * 64 bit math
	 * First changing tick into fsec
	 * Then 64 bit div to find number of hpet clk per tick
	 */
	ASM_MUL64_REG(tick_fsec_low, tick_fsec_high,
			KERNEL_TICK_USEC, FSEC_TO_USEC);
	ASM_DIV64_REG(hpet_tick, hpet_tick_rem,
			hpet_period, tick_fsec_low, tick_fsec_high);

	if (hpet_tick_rem > (hpet_period >> 1))
		hpet_tick++; /* rounding the result */

	hpet_use_timer = id & HPET_ID_LEGSUP;

	if (hpet_timer_stop_set_go(hpet_tick))
		return -1;

	use_hpet = 1;

#ifdef	CONFIG_HPET
	{
		struct hpet_data	hd;
		unsigned int 		ntimer;

		memset(&hd, 0, sizeof (hd));

		ntimer = hpet_readl(HPET_ID);
		ntimer = (ntimer & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT;
		ntimer++;

		/*
		 * Register with driver.
		 * Timer0 and Timer1 is used by platform.
		 */
		hd.hd_phys_address = hpet_address;
		hd.hd_address = hpet_virt_address;
		hd.hd_nirqs = ntimer;
		hd.hd_flags = HPET_DATA_PLATFORM;
		hpet_reserve_timer(&hd, 0);
#ifdef	CONFIG_HPET_EMULATE_RTC
		hpet_reserve_timer(&hd, 1);
#endif
		hd.hd_irq[0] = HPET_LEGACY_8254;
		hd.hd_irq[1] = HPET_LEGACY_RTC;
		if (ntimer > 2) {
			struct hpet __iomem	*hpet;
			struct hpet_timer __iomem *timer;
			int			i;

			hpet = hpet_virt_address;

			for (i = 2, timer = &hpet->hpet_timers[2]; i < ntimer;
				timer++, i++)
				hd.hd_irq[i] = (timer->hpet_config &
					Tn_INT_ROUTE_CNF_MASK) >>
					Tn_INT_ROUTE_CNF_SHIFT;

		}

		hpet_alloc(&hd);
	}
#endif

#ifdef CONFIG_X86_LOCAL_APIC
	if (hpet_use_timer)
		wait_timer_tick = wait_hpet_tick;
#endif
	return 0;
}

int hpet_reenable(void)
{
	return hpet_timer_stop_set_go(hpet_tick);
}

int is_hpet_enabled(void)
{
	return use_hpet;
}

int is_hpet_capable(void)
{
	if (!boot_hpet_disable && hpet_address)
		return 1;
	return 0;
}

static int __init hpet_setup(char* str)
{
	if (str) {
		if (!strncmp("disable", str, 7))
			boot_hpet_disable = 1;
	}
	return 1;
}

__setup("hpet=", hpet_setup);

#ifdef CONFIG_HPET_EMULATE_RTC
/* HPET in LegacyReplacement Mode eats up RTC interrupt line. When, HPET
 * is enabled, we support RTC interrupt functionality in software.
 * RTC has 3 kinds of interrupts:
 * 1) Update Interrupt - generate an interrupt, every sec, when RTC clock
 *    is updated
 * 2) Alarm Interrupt - generate an interrupt at a specific time of day
 * 3) Periodic Interrupt - generate periodic interrupt, with frequencies
 *    2Hz-8192Hz (2Hz-64Hz for non-root user) (all freqs in powers of 2)
 * (1) and (2) above are implemented using polling at a frequency of
 * 64 Hz. The exact frequency is a tradeoff between accuracy and interrupt
 * overhead. (DEFAULT_RTC_INT_FREQ)
 * For (3), we use interrupts at 64Hz or user specified periodic
 * frequency, whichever is higher.
 */
#include <linux/mc146818rtc.h>
#include <linux/rtc.h>

#define DEFAULT_RTC_INT_FREQ 	64
#define RTC_NUM_INTS 		1

static unsigned long UIE_on;
static unsigned long prev_update_sec;

static unsigned long AIE_on;
static struct rtc_time alarm_time;

static unsigned long PIE_on;
static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ;
static unsigned long PIE_count;

static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
static unsigned int hpet_t1_cmp; /* cached comparator register */

/*
 * Timer 1 for RTC, we do not use periodic interrupt feature,
 * even if HPET supports periodic interrupts on Timer 1.
 * The reason being, to set up a periodic interrupt in HPET, we need to
 * stop the main counter. And if we do that everytime someone diables/enables
 * RTC, we will have adverse effect on main kernel timer running on Timer 0.
 * So, for the time being, simulate the periodic interrupt in software.
 *
 * hpet_rtc_timer_init() is called for the first time and during subsequent
 * interuppts reinit happens through hpet_rtc_timer_reinit().
 */
int hpet_rtc_timer_init(void)
{
	unsigned int cfg, cnt;
	unsigned long flags;

	if (!is_hpet_enabled())
		return 0;
	/*
	 * Set the counter 1 and enable the interrupts.
	 */
	if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
		hpet_rtc_int_freq = PIE_freq;
	else
		hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;

	local_irq_save(flags);
	cnt = hpet_readl(HPET_COUNTER);
	cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
	hpet_writel(cnt, HPET_T1_CMP);
	hpet_t1_cmp = cnt;
	local_irq_restore(flags);

	cfg = hpet_readl(HPET_T1_CFG);
	cfg &= ~HPET_TN_PERIODIC;
	cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
	hpet_writel(cfg, HPET_T1_CFG);

	return 1;
}

static void hpet_rtc_timer_reinit(void)
{
	unsigned int cfg, cnt;

	if (unlikely(!(PIE_on | AIE_on | UIE_on))) {
		cfg = hpet_readl(HPET_T1_CFG);
		cfg &= ~HPET_TN_ENABLE;
		hpet_writel(cfg, HPET_T1_CFG);
		return;
	}

	if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
		hpet_rtc_int_freq = PIE_freq;
	else
		hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;

	/* It is more accurate to use the comparator value than current count.*/
	cnt = hpet_t1_cmp;
	cnt += hpet_tick*HZ/hpet_rtc_int_freq;
	hpet_writel(cnt, HPET_T1_CMP);
	hpet_t1_cmp = cnt;
}

/*
 * The functions below are called from rtc driver.
 * Return 0 if HPET is not being used.
 * Otherwise do the necessary changes and return 1.
 */
int hpet_mask_rtc_irq_bit(unsigned long bit_mask)
{
	if (!is_hpet_enabled())
		return 0;

	if (bit_mask & RTC_UIE)
		UIE_on = 0;
	if (bit_mask & RTC_PIE)
		PIE_on = 0;
	if (bit_mask & RTC_AIE)
		AIE_on = 0;

	return 1;
}

int hpet_set_rtc_irq_bit(unsigned long bit_mask)
{
	int timer_init_reqd = 0;

	if (!is_hpet_enabled())
		return 0;

	if (!(PIE_on | AIE_on | UIE_on))
		timer_init_reqd = 1;

	if (bit_mask & RTC_UIE) {
		UIE_on = 1;
	}
	if (bit_mask & RTC_PIE) {
		PIE_on = 1;
		PIE_count = 0;
	}
	if (bit_mask & RTC_AIE) {
		AIE_on = 1;
	}

	if (timer_init_reqd)
		hpet_rtc_timer_init();

	return 1;
}

int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec)
{
	if (!is_hpet_enabled())
		return 0;

	alarm_time.tm_hour = hrs;
	alarm_time.tm_min = min;
	alarm_time.tm_sec = sec;

	return 1;
}

int hpet_set_periodic_freq(unsigned long freq)
{
	if (!is_hpet_enabled())
		return 0;

	PIE_freq = freq;
	PIE_count = 0;

	return 1;
}

int hpet_rtc_dropped_irq(void)
{
	if (!is_hpet_enabled())
		return 0;

	return 1;
}

irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	struct rtc_time curr_time;
	unsigned long rtc_int_flag = 0;
	int call_rtc_interrupt = 0;

	hpet_rtc_timer_reinit();

	if (UIE_on | AIE_on) {
		rtc_get_rtc_time(&curr_time);
	}
	if (UIE_on) {
		if (curr_time.tm_sec != prev_update_sec) {
			/* Set update int info, call real rtc int routine */
			call_rtc_interrupt = 1;
			rtc_int_flag = RTC_UF;
			prev_update_sec = curr_time.tm_sec;
		}
	}
	if (PIE_on) {
		PIE_count++;
		if (PIE_count >= hpet_rtc_int_freq/PIE_freq) {
			/* Set periodic int info, call real rtc int routine */
			call_rtc_interrupt = 1;
			rtc_int_flag |= RTC_PF;
			PIE_count = 0;
		}
	}
	if (AIE_on) {
		if ((curr_time.tm_sec == alarm_time.tm_sec) &&
		    (curr_time.tm_min == alarm_time.tm_min) &&
		    (curr_time.tm_hour == alarm_time.tm_hour)) {
			/* Set alarm int info, call real rtc int routine */
			call_rtc_interrupt = 1;
			rtc_int_flag |= RTC_AF;
		}
	}
	if (call_rtc_interrupt) {
		rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8));
		rtc_interrupt(rtc_int_flag, dev_id, regs);
	}
	return IRQ_HANDLED;
}
#endif

