/*
 * intel_mid_vrtc.c: Driver for virtual RTC device on Intel MID platform
 *
 * (C) Copyright 2009 Intel Corporation
 *
 * 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; version 2
 * of the License.
 *
 * Note:
 * VRTC is emulated by system controller firmware, the real HW
 * RTC is located in the PMIC device. SCU FW shadows PMIC RTC
 * in a memory mapped IO space that is visible to the host IA
 * processor.
 *
 * This driver is based on RTC CMOS driver.
 */

#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/init.h>
#include <linux/sfi.h>
#include <linux/platform_device.h>
#include <linux/mc146818rtc.h>

#include <asm/intel-mid.h>
#include <asm/intel_mid_vrtc.h>
#include <asm/time.h>
#include <asm/fixmap.h>

static unsigned char __iomem *vrtc_virt_base;

unsigned char vrtc_cmos_read(unsigned char reg)
{
	unsigned char retval;

	/* vRTC's registers range from 0x0 to 0xD */
	if (reg > 0xd || !vrtc_virt_base)
		return 0xff;

	lock_cmos_prefix(reg);
	retval = __raw_readb(vrtc_virt_base + (reg << 2));
	lock_cmos_suffix(reg);
	return retval;
}
EXPORT_SYMBOL_GPL(vrtc_cmos_read);

void vrtc_cmos_write(unsigned char val, unsigned char reg)
{
	if (reg > 0xd || !vrtc_virt_base)
		return;

	lock_cmos_prefix(reg);
	__raw_writeb(val, vrtc_virt_base + (reg << 2));
	lock_cmos_suffix(reg);
}
EXPORT_SYMBOL_GPL(vrtc_cmos_write);

void vrtc_get_time(struct timespec *now)
{
	u8 sec, min, hour, mday, mon;
	unsigned long flags;
	u32 year;

	spin_lock_irqsave(&rtc_lock, flags);

	while ((vrtc_cmos_read(RTC_FREQ_SELECT) & RTC_UIP))
		cpu_relax();

	sec = vrtc_cmos_read(RTC_SECONDS);
	min = vrtc_cmos_read(RTC_MINUTES);
	hour = vrtc_cmos_read(RTC_HOURS);
	mday = vrtc_cmos_read(RTC_DAY_OF_MONTH);
	mon = vrtc_cmos_read(RTC_MONTH);
	year = vrtc_cmos_read(RTC_YEAR);

	spin_unlock_irqrestore(&rtc_lock, flags);

	/* vRTC YEAR reg contains the offset to 1972 */
	year += 1972;

	pr_info("vRTC: sec: %d min: %d hour: %d day: %d "
		"mon: %d year: %d\n", sec, min, hour, mday, mon, year);

	now->tv_sec = mktime(year, mon, mday, hour, min, sec);
	now->tv_nsec = 0;
}

int vrtc_set_mmss(const struct timespec *now)
{
	unsigned long flags;
	struct rtc_time tm;
	int year;
	int retval = 0;

	rtc_time_to_tm(now->tv_sec, &tm);
	if (!rtc_valid_tm(&tm) && tm.tm_year >= 72) {
		/*
		 * tm.year is the number of years since 1900, and the
		 * vrtc need the years since 1972.
		 */
		year = tm.tm_year - 72;
		spin_lock_irqsave(&rtc_lock, flags);
		vrtc_cmos_write(year, RTC_YEAR);
		vrtc_cmos_write(tm.tm_mon, RTC_MONTH);
		vrtc_cmos_write(tm.tm_mday, RTC_DAY_OF_MONTH);
		vrtc_cmos_write(tm.tm_hour, RTC_HOURS);
		vrtc_cmos_write(tm.tm_min, RTC_MINUTES);
		vrtc_cmos_write(tm.tm_sec, RTC_SECONDS);
		spin_unlock_irqrestore(&rtc_lock, flags);
	} else {
		pr_err("%s: Invalid vRTC value: write of %lx to vRTC failed\n",
			__func__, now->tv_sec);
		retval = -EINVAL;
	}
	return retval;
}

void __init intel_mid_rtc_init(void)
{
	unsigned long vrtc_paddr;

	sfi_table_parse(SFI_SIG_MRTC, NULL, NULL, sfi_parse_mrtc);

	vrtc_paddr = sfi_mrtc_array[0].phys_addr;
	if (!sfi_mrtc_num || !vrtc_paddr)
		return;

	vrtc_virt_base = (void __iomem *)set_fixmap_offset_nocache(FIX_LNW_VRTC,
								vrtc_paddr);
	x86_platform.get_wallclock = vrtc_get_time;
	x86_platform.set_wallclock = vrtc_set_mmss;
}

/*
 * The Moorestown platform has a memory mapped virtual RTC device that emulates
 * the programming interface of the RTC.
 */

static struct resource vrtc_resources[] = {
	[0] = {
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.flags	= IORESOURCE_IRQ,
	}
};

static struct platform_device vrtc_device = {
	.name		= "rtc_mrst",
	.id		= -1,
	.resource	= vrtc_resources,
	.num_resources	= ARRAY_SIZE(vrtc_resources),
};

/* Register the RTC device if appropriate */
static int __init intel_mid_device_create(void)
{
	/* No Moorestown, no device */
	if (!intel_mid_identify_cpu())
		return -ENODEV;
	/* No timer, no device */
	if (!sfi_mrtc_num)
		return -ENODEV;

	/* iomem resource */
	vrtc_resources[0].start = sfi_mrtc_array[0].phys_addr;
	vrtc_resources[0].end = sfi_mrtc_array[0].phys_addr +
				MRST_VRTC_MAP_SZ;
	/* irq resource */
	vrtc_resources[1].start = sfi_mrtc_array[0].irq;
	vrtc_resources[1].end = sfi_mrtc_array[0].irq;

	return platform_device_register(&vrtc_device);
}
device_initcall(intel_mid_device_create);
