/*
 * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.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.
 */

#include <linux/clk.h>
#include <linux/interrupt.h>
#include <asm/time.h>

#include <loongson1.h>
#include <platform.h>

#ifdef CONFIG_CEVT_CSRC_LS1X

#if defined(CONFIG_TIMER_USE_PWM1)
#define LS1X_TIMER_BASE	LS1X_PWM1_BASE
#define LS1X_TIMER_IRQ	LS1X_PWM1_IRQ

#elif defined(CONFIG_TIMER_USE_PWM2)
#define LS1X_TIMER_BASE	LS1X_PWM2_BASE
#define LS1X_TIMER_IRQ	LS1X_PWM2_IRQ

#elif defined(CONFIG_TIMER_USE_PWM3)
#define LS1X_TIMER_BASE	LS1X_PWM3_BASE
#define LS1X_TIMER_IRQ	LS1X_PWM3_IRQ

#else
#define LS1X_TIMER_BASE	LS1X_PWM0_BASE
#define LS1X_TIMER_IRQ	LS1X_PWM0_IRQ
#endif

DEFINE_RAW_SPINLOCK(ls1x_timer_lock);

static void __iomem *timer_base;
static uint32_t ls1x_jiffies_per_tick;

static inline void ls1x_pwmtimer_set_period(uint32_t period)
{
	__raw_writel(period, timer_base + PWM_HRC);
	__raw_writel(period, timer_base + PWM_LRC);
}

static inline void ls1x_pwmtimer_restart(void)
{
	__raw_writel(0x0, timer_base + PWM_CNT);
	__raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL);
}

void __init ls1x_pwmtimer_init(void)
{
	timer_base = ioremap(LS1X_TIMER_BASE, 0xf);
	if (!timer_base)
		panic("Failed to remap timer registers");

	ls1x_jiffies_per_tick = DIV_ROUND_CLOSEST(mips_hpt_frequency, HZ);

	ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick);
	ls1x_pwmtimer_restart();
}

static cycle_t ls1x_clocksource_read(struct clocksource *cs)
{
	unsigned long flags;
	int count;
	u32 jifs;
	static int old_count;
	static u32 old_jifs;

	raw_spin_lock_irqsave(&ls1x_timer_lock, flags);
	/*
	 * Although our caller may have the read side of xtime_lock,
	 * this is now a seqlock, and we are cheating in this routine
	 * by having side effects on state that we cannot undo if
	 * there is a collision on the seqlock and our caller has to
	 * retry.  (Namely, old_jifs and old_count.)  So we must treat
	 * jiffies as volatile despite the lock.  We read jiffies
	 * before latching the timer count to guarantee that although
	 * the jiffies value might be older than the count (that is,
	 * the counter may underflow between the last point where
	 * jiffies was incremented and the point where we latch the
	 * count), it cannot be newer.
	 */
	jifs = jiffies;
	/* read the count */
	count = __raw_readl(timer_base + PWM_CNT);

	/*
	 * It's possible for count to appear to go the wrong way for this
	 * reason:
	 *
	 *  The timer counter underflows, but we haven't handled the resulting
	 *  interrupt and incremented jiffies yet.
	 *
	 * Previous attempts to handle these cases intelligently were buggy, so
	 * we just do the simple thing now.
	 */
	if (count < old_count && jifs == old_jifs)
		count = old_count;

	old_count = count;
	old_jifs = jifs;

	raw_spin_unlock_irqrestore(&ls1x_timer_lock, flags);

	return (cycle_t) (jifs * ls1x_jiffies_per_tick) + count;
}

static struct clocksource ls1x_clocksource = {
	.name		= "ls1x-pwmtimer",
	.read		= ls1x_clocksource_read,
	.mask		= CLOCKSOURCE_MASK(24),
	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
};

static irqreturn_t ls1x_clockevent_isr(int irq, void *devid)
{
	struct clock_event_device *cd = devid;

	ls1x_pwmtimer_restart();
	cd->event_handler(cd);

	return IRQ_HANDLED;
}

static void ls1x_clockevent_set_mode(enum clock_event_mode mode,
				     struct clock_event_device *cd)
{
	raw_spin_lock(&ls1x_timer_lock);
	switch (mode) {
	case CLOCK_EVT_MODE_PERIODIC:
		ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick);
		ls1x_pwmtimer_restart();
	case CLOCK_EVT_MODE_RESUME:
		__raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL);
		break;
	case CLOCK_EVT_MODE_ONESHOT:
	case CLOCK_EVT_MODE_SHUTDOWN:
		__raw_writel(__raw_readl(timer_base + PWM_CTRL) & ~CNT_EN,
			     timer_base + PWM_CTRL);
		break;
	default:
		break;
	}
	raw_spin_unlock(&ls1x_timer_lock);
}

static int ls1x_clockevent_set_next(unsigned long evt,
				    struct clock_event_device *cd)
{
	raw_spin_lock(&ls1x_timer_lock);
	ls1x_pwmtimer_set_period(evt);
	ls1x_pwmtimer_restart();
	raw_spin_unlock(&ls1x_timer_lock);

	return 0;
}

static struct clock_event_device ls1x_clockevent = {
	.name		= "ls1x-pwmtimer",
	.features	= CLOCK_EVT_FEAT_PERIODIC,
	.rating		= 300,
	.irq		= LS1X_TIMER_IRQ,
	.set_next_event	= ls1x_clockevent_set_next,
	.set_mode	= ls1x_clockevent_set_mode,
};

static struct irqaction ls1x_pwmtimer_irqaction = {
	.name		= "ls1x-pwmtimer",
	.handler	= ls1x_clockevent_isr,
	.dev_id		= &ls1x_clockevent,
	.flags		= IRQF_PERCPU | IRQF_TIMER,
};

static void __init ls1x_time_init(void)
{
	struct clock_event_device *cd = &ls1x_clockevent;
	int ret;

	if (!mips_hpt_frequency)
		panic("Invalid timer clock rate");

	ls1x_pwmtimer_init();

	clockevent_set_clock(cd, mips_hpt_frequency);
	cd->max_delta_ns = clockevent_delta2ns(0xffffff, cd);
	cd->min_delta_ns = clockevent_delta2ns(0x000300, cd);
	cd->cpumask = cpumask_of(smp_processor_id());
	clockevents_register_device(cd);

	ls1x_clocksource.rating = 200 + mips_hpt_frequency / 10000000;
	ret = clocksource_register_hz(&ls1x_clocksource, mips_hpt_frequency);
	if (ret)
		panic(KERN_ERR "Failed to register clocksource: %d\n", ret);

	setup_irq(LS1X_TIMER_IRQ, &ls1x_pwmtimer_irqaction);
}
#endif /* CONFIG_CEVT_CSRC_LS1X */

void __init plat_time_init(void)
{
	struct clk *clk = NULL;

	/* initialize LS1X clocks */
	ls1x_clk_init();

#ifdef CONFIG_CEVT_CSRC_LS1X
	/* setup LS1X PWM timer */
	clk = clk_get(NULL, "ls1x_pwmtimer");
	if (IS_ERR(clk))
		panic("unable to get timer clock, err=%ld", PTR_ERR(clk));

	mips_hpt_frequency = clk_get_rate(clk);
	ls1x_time_init();
#else
	/* setup mips r4k timer */
	clk = clk_get(NULL, "cpu_clk");
	if (IS_ERR(clk))
		panic("unable to get cpu clock, err=%ld", PTR_ERR(clk));

	mips_hpt_frequency = clk_get_rate(clk) / 2;
#endif /* CONFIG_CEVT_CSRC_LS1X */
}
