/*
 * SGI RTC clock/timer routines.
 *
 *  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.
 *
 *  This program is distributed in the hope that 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
 *
 *  Copyright (c) 2009-2013 Silicon Graphics, Inc.  All Rights Reserved.
 *  Copyright (c) Dimitri Sivanich
 */
#include <linux/clockchips.h>
#include <linux/slab.h>

#include <asm/uv/uv_mmrs.h>
#include <asm/uv/uv_hub.h>
#include <asm/uv/bios.h>
#include <asm/uv/uv.h>
#include <asm/apic.h>
#include <asm/cpu.h>

#define RTC_NAME		"sgi_rtc"

static cycle_t uv_read_rtc(struct clocksource *cs);
static int uv_rtc_next_event(unsigned long, struct clock_event_device *);
static int uv_rtc_shutdown(struct clock_event_device *evt);

static struct clocksource clocksource_uv = {
	.name		= RTC_NAME,
	.rating		= 299,
	.read		= uv_read_rtc,
	.mask		= (cycle_t)UVH_RTC_REAL_TIME_CLOCK_MASK,
	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
};

static struct clock_event_device clock_event_device_uv = {
	.name			= RTC_NAME,
	.features		= CLOCK_EVT_FEAT_ONESHOT,
	.shift			= 20,
	.rating			= 400,
	.irq			= -1,
	.set_next_event		= uv_rtc_next_event,
	.set_state_shutdown	= uv_rtc_shutdown,
	.event_handler		= NULL,
};

static DEFINE_PER_CPU(struct clock_event_device, cpu_ced);

/* There is one of these allocated per node */
struct uv_rtc_timer_head {
	spinlock_t	lock;
	/* next cpu waiting for timer, local node relative: */
	int		next_cpu;
	/* number of cpus on this node: */
	int		ncpus;
	struct {
		int	lcpu;		/* systemwide logical cpu number */
		u64	expires;	/* next timer expiration for this cpu */
	} cpu[1];
};

/*
 * Access to uv_rtc_timer_head via blade id.
 */
static struct uv_rtc_timer_head		**blade_info __read_mostly;

static int				uv_rtc_evt_enable;

/*
 * Hardware interface routines
 */

/* Send IPIs to another node */
static void uv_rtc_send_IPI(int cpu)
{
	unsigned long apicid, val;
	int pnode;

	apicid = cpu_physical_id(cpu);
	pnode = uv_apicid_to_pnode(apicid);
	apicid |= uv_apicid_hibits;
	val = (1UL << UVH_IPI_INT_SEND_SHFT) |
	      (apicid << UVH_IPI_INT_APIC_ID_SHFT) |
	      (X86_PLATFORM_IPI_VECTOR << UVH_IPI_INT_VECTOR_SHFT);

	uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
}

/* Check for an RTC interrupt pending */
static int uv_intr_pending(int pnode)
{
	if (is_uv1_hub())
		return uv_read_global_mmr64(pnode, UVH_EVENT_OCCURRED0) &
			UV1H_EVENT_OCCURRED0_RTC1_MASK;
	else if (is_uvx_hub())
		return uv_read_global_mmr64(pnode, UVXH_EVENT_OCCURRED2) &
			UVXH_EVENT_OCCURRED2_RTC_1_MASK;
	return 0;
}

/* Setup interrupt and return non-zero if early expiration occurred. */
static int uv_setup_intr(int cpu, u64 expires)
{
	u64 val;
	unsigned long apicid = cpu_physical_id(cpu) | uv_apicid_hibits;
	int pnode = uv_cpu_to_pnode(cpu);

	uv_write_global_mmr64(pnode, UVH_RTC1_INT_CONFIG,
		UVH_RTC1_INT_CONFIG_M_MASK);
	uv_write_global_mmr64(pnode, UVH_INT_CMPB, -1L);

	if (is_uv1_hub())
		uv_write_global_mmr64(pnode, UVH_EVENT_OCCURRED0_ALIAS,
				UV1H_EVENT_OCCURRED0_RTC1_MASK);
	else
		uv_write_global_mmr64(pnode, UVXH_EVENT_OCCURRED2_ALIAS,
				UVXH_EVENT_OCCURRED2_RTC_1_MASK);

	val = (X86_PLATFORM_IPI_VECTOR << UVH_RTC1_INT_CONFIG_VECTOR_SHFT) |
		((u64)apicid << UVH_RTC1_INT_CONFIG_APIC_ID_SHFT);

	/* Set configuration */
	uv_write_global_mmr64(pnode, UVH_RTC1_INT_CONFIG, val);
	/* Initialize comparator value */
	uv_write_global_mmr64(pnode, UVH_INT_CMPB, expires);

	if (uv_read_rtc(NULL) <= expires)
		return 0;

	return !uv_intr_pending(pnode);
}

/*
 * Per-cpu timer tracking routines
 */

static __init void uv_rtc_deallocate_timers(void)
{
	int bid;

	for_each_possible_blade(bid) {
		kfree(blade_info[bid]);
	}
	kfree(blade_info);
}

/* Allocate per-node list of cpu timer expiration times. */
static __init int uv_rtc_allocate_timers(void)
{
	int cpu;

	blade_info = kzalloc(uv_possible_blades * sizeof(void *), GFP_KERNEL);
	if (!blade_info)
		return -ENOMEM;

	for_each_present_cpu(cpu) {
		int nid = cpu_to_node(cpu);
		int bid = uv_cpu_to_blade_id(cpu);
		int bcpu = uv_cpu_blade_processor_id(cpu);
		struct uv_rtc_timer_head *head = blade_info[bid];

		if (!head) {
			head = kmalloc_node(sizeof(struct uv_rtc_timer_head) +
				(uv_blade_nr_possible_cpus(bid) *
					2 * sizeof(u64)),
				GFP_KERNEL, nid);
			if (!head) {
				uv_rtc_deallocate_timers();
				return -ENOMEM;
			}
			spin_lock_init(&head->lock);
			head->ncpus = uv_blade_nr_possible_cpus(bid);
			head->next_cpu = -1;
			blade_info[bid] = head;
		}

		head->cpu[bcpu].lcpu = cpu;
		head->cpu[bcpu].expires = ULLONG_MAX;
	}

	return 0;
}

/* Find and set the next expiring timer.  */
static void uv_rtc_find_next_timer(struct uv_rtc_timer_head *head, int pnode)
{
	u64 lowest = ULLONG_MAX;
	int c, bcpu = -1;

	head->next_cpu = -1;
	for (c = 0; c < head->ncpus; c++) {
		u64 exp = head->cpu[c].expires;
		if (exp < lowest) {
			bcpu = c;
			lowest = exp;
		}
	}
	if (bcpu >= 0) {
		head->next_cpu = bcpu;
		c = head->cpu[bcpu].lcpu;
		if (uv_setup_intr(c, lowest))
			/* If we didn't set it up in time, trigger */
			uv_rtc_send_IPI(c);
	} else {
		uv_write_global_mmr64(pnode, UVH_RTC1_INT_CONFIG,
			UVH_RTC1_INT_CONFIG_M_MASK);
	}
}

/*
 * Set expiration time for current cpu.
 *
 * Returns 1 if we missed the expiration time.
 */
static int uv_rtc_set_timer(int cpu, u64 expires)
{
	int pnode = uv_cpu_to_pnode(cpu);
	int bid = uv_cpu_to_blade_id(cpu);
	struct uv_rtc_timer_head *head = blade_info[bid];
	int bcpu = uv_cpu_blade_processor_id(cpu);
	u64 *t = &head->cpu[bcpu].expires;
	unsigned long flags;
	int next_cpu;

	spin_lock_irqsave(&head->lock, flags);

	next_cpu = head->next_cpu;
	*t = expires;

	/* Will this one be next to go off? */
	if (next_cpu < 0 || bcpu == next_cpu ||
			expires < head->cpu[next_cpu].expires) {
		head->next_cpu = bcpu;
		if (uv_setup_intr(cpu, expires)) {
			*t = ULLONG_MAX;
			uv_rtc_find_next_timer(head, pnode);
			spin_unlock_irqrestore(&head->lock, flags);
			return -ETIME;
		}
	}

	spin_unlock_irqrestore(&head->lock, flags);
	return 0;
}

/*
 * Unset expiration time for current cpu.
 *
 * Returns 1 if this timer was pending.
 */
static int uv_rtc_unset_timer(int cpu, int force)
{
	int pnode = uv_cpu_to_pnode(cpu);
	int bid = uv_cpu_to_blade_id(cpu);
	struct uv_rtc_timer_head *head = blade_info[bid];
	int bcpu = uv_cpu_blade_processor_id(cpu);
	u64 *t = &head->cpu[bcpu].expires;
	unsigned long flags;
	int rc = 0;

	spin_lock_irqsave(&head->lock, flags);

	if ((head->next_cpu == bcpu && uv_read_rtc(NULL) >= *t) || force)
		rc = 1;

	if (rc) {
		*t = ULLONG_MAX;
		/* Was the hardware setup for this timer? */
		if (head->next_cpu == bcpu)
			uv_rtc_find_next_timer(head, pnode);
	}

	spin_unlock_irqrestore(&head->lock, flags);

	return rc;
}


/*
 * Kernel interface routines.
 */

/*
 * Read the RTC.
 *
 * Starting with HUB rev 2.0, the UV RTC register is replicated across all
 * cachelines of it's own page.  This allows faster simultaneous reads
 * from a given socket.
 */
static cycle_t uv_read_rtc(struct clocksource *cs)
{
	unsigned long offset;

	if (uv_get_min_hub_revision_id() == 1)
		offset = 0;
	else
		offset = (uv_blade_processor_id() * L1_CACHE_BYTES) % PAGE_SIZE;

	return (cycle_t)uv_read_local_mmr(UVH_RTC | offset);
}

/*
 * Program the next event, relative to now
 */
static int uv_rtc_next_event(unsigned long delta,
			     struct clock_event_device *ced)
{
	int ced_cpu = cpumask_first(ced->cpumask);

	return uv_rtc_set_timer(ced_cpu, delta + uv_read_rtc(NULL));
}

/*
 * Shutdown the RTC timer
 */
static int uv_rtc_shutdown(struct clock_event_device *evt)
{
	int ced_cpu = cpumask_first(evt->cpumask);

	uv_rtc_unset_timer(ced_cpu, 1);
	return 0;
}

static void uv_rtc_interrupt(void)
{
	int cpu = smp_processor_id();
	struct clock_event_device *ced = &per_cpu(cpu_ced, cpu);

	if (!ced || !ced->event_handler)
		return;

	if (uv_rtc_unset_timer(cpu, 0) != 1)
		return;

	ced->event_handler(ced);
}

static int __init uv_enable_evt_rtc(char *str)
{
	uv_rtc_evt_enable = 1;

	return 1;
}
__setup("uvrtcevt", uv_enable_evt_rtc);

static __init void uv_rtc_register_clockevents(struct work_struct *dummy)
{
	struct clock_event_device *ced = this_cpu_ptr(&cpu_ced);

	*ced = clock_event_device_uv;
	ced->cpumask = cpumask_of(smp_processor_id());
	clockevents_register_device(ced);
}

static __init int uv_rtc_setup_clock(void)
{
	int rc;

	if (!is_uv_system())
		return -ENODEV;

	rc = clocksource_register_hz(&clocksource_uv, sn_rtc_cycles_per_second);
	if (rc)
		printk(KERN_INFO "UV RTC clocksource failed rc %d\n", rc);
	else
		printk(KERN_INFO "UV RTC clocksource registered freq %lu MHz\n",
			sn_rtc_cycles_per_second/(unsigned long)1E6);

	if (rc || !uv_rtc_evt_enable || x86_platform_ipi_callback)
		return rc;

	/* Setup and register clockevents */
	rc = uv_rtc_allocate_timers();
	if (rc)
		goto error;

	x86_platform_ipi_callback = uv_rtc_interrupt;

	clock_event_device_uv.mult = div_sc(sn_rtc_cycles_per_second,
				NSEC_PER_SEC, clock_event_device_uv.shift);

	clock_event_device_uv.min_delta_ns = NSEC_PER_SEC /
						sn_rtc_cycles_per_second;

	clock_event_device_uv.max_delta_ns = clocksource_uv.mask *
				(NSEC_PER_SEC / sn_rtc_cycles_per_second);

	rc = schedule_on_each_cpu(uv_rtc_register_clockevents);
	if (rc) {
		x86_platform_ipi_callback = NULL;
		uv_rtc_deallocate_timers();
		goto error;
	}

	printk(KERN_INFO "UV RTC clockevents registered\n");

	return 0;

error:
	clocksource_unregister(&clocksource_uv);
	printk(KERN_INFO "UV RTC clockevents failed rc %d\n", rc);

	return rc;
}
arch_initcall(uv_rtc_setup_clock);
