From: Jacob Pan <jacob.jun.pan@linux.intel.com>
To: LKML <linux-kernel@vger.kernel.org>,
"H. Peter Anvin" <hpa@zytor.com>, Ingo Molnar <mingo@elte.hu>,
Thomas Gleixner <tglx@linutronix.de>,
Alan Cox <alan@linux.intel.com>,
Arjan van de Ven <arjan@linux.intel.com>
Cc: Feng Tang <feng.tang@intel.com>,
Jacob Pan <jacob.jun.pan@linux.intel.com>
Subject: [PATCH 6/8] x86/mrst: add vrtc driver which serves as a wall clock device
Date: Fri, 14 May 2010 14:41:19 -0700 [thread overview]
Message-ID: <1273873281-17489-7-git-send-email-jacob.jun.pan@linux.intel.com> (raw)
In-Reply-To: <1273873281-17489-1-git-send-email-jacob.jun.pan@linux.intel.com>
From: Feng Tang <feng.tang@intel.com>
Moorestown platform doesn't have a m146818 RTC device like traditional
x86 PC, but a firmware emulated virtual RTC device(vrtc), which provides
some basic RTC functions like get/set time. vrtc serves as the only
wall clock device on Moorestown platform.
Signed-off-by: Feng Tang <feng.tang@intel.com>
Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
---
arch/x86/include/asm/fixmap.h | 4 ++
arch/x86/include/asm/vrtc.h | 27 +++++++++++
arch/x86/kernel/Makefile | 2 +-
arch/x86/kernel/mrst.c | 20 ++++++++
arch/x86/kernel/vrtc.c | 100 +++++++++++++++++++++++++++++++++++++++++
5 files changed, 152 insertions(+), 1 deletions(-)
create mode 100644 arch/x86/include/asm/vrtc.h
create mode 100644 arch/x86/kernel/vrtc.c
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index d07b44f..c4ba8d9 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -117,6 +117,10 @@ enum fixed_addresses {
FIX_TEXT_POKE1, /* reserve 2 pages for text_poke() */
FIX_TEXT_POKE0, /* first page is last, because allocation is backward */
__end_of_permanent_fixed_addresses,
+
+#ifdef CONFIG_X86_MRST
+ FIX_LNW_VRTC,
+#endif
/*
* 256 temporary boot-time mappings, used by early_ioremap(),
* before ioremap() is functional.
diff --git a/arch/x86/include/asm/vrtc.h b/arch/x86/include/asm/vrtc.h
new file mode 100644
index 0000000..4e40129
--- /dev/null
+++ b/arch/x86/include/asm/vrtc.h
@@ -0,0 +1,27 @@
+#ifndef _MRST_VRTC_H
+#define _MRST_VRTC_H
+
+#ifdef CONFIG_X86_MRST
+extern unsigned char vrtc_cmos_read(unsigned char reg);
+extern void vrtc_cmos_write(unsigned char val, unsigned char reg);
+extern unsigned long vrtc_get_time(void);
+extern int vrtc_set_mmss(unsigned long nowtime);
+extern void vrtc_set_base(void __iomem *base);
+
+#define MRST_VRTC_PGOFFSET (0xc00)
+
+#else
+static inline unsigned char vrtc_cmos_read(unsigned char reg)
+{
+ return 0xff;
+}
+
+static inline void vrtc_cmos_write(unsigned char val, unsigned char reg)
+{
+ return;
+}
+#endif
+
+#define MRST_VRTC_MAP_SZ (1024)
+
+#endif
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index e77b220..f3fdcbe 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -104,7 +104,7 @@ obj-$(CONFIG_SCx200) += scx200.o
scx200-y += scx200_32.o
obj-$(CONFIG_OLPC) += olpc.o
-obj-$(CONFIG_X86_MRST) += mrst.o
+obj-$(CONFIG_X86_MRST) += mrst.o vrtc.o
microcode-y := microcode_core.o
microcode-$(CONFIG_MICROCODE_INTEL) += microcode_intel.o
diff --git a/arch/x86/kernel/mrst.c b/arch/x86/kernel/mrst.c
index 339d7f5..83c23d6 100644
--- a/arch/x86/kernel/mrst.c
+++ b/arch/x86/kernel/mrst.c
@@ -24,6 +24,7 @@
#include <asm/io.h>
#include <asm/i8259.h>
#include <asm/apb_timer.h>
+#include <asm/vrtc.h>
/**
* the clockevent devices on Moorestown/Medfield can be APBT or LAPIC clock,
@@ -234,7 +235,24 @@ void __init mrst_time_init(void)
void __init mrst_rtc_init(void)
{
+ unsigned long rtc_paddr;
+ void __iomem *virt_base;
+
sfi_table_parse(SFI_SIG_MRTC, NULL, NULL, sfi_parse_mrtc);
+ if (!sfi_mrtc_num)
+ return;
+
+ rtc_paddr = sfi_mrtc_array[0].phys_addr;
+
+ /* vRTC's register address may not be page aligned */
+ set_fixmap_nocache(FIX_LNW_VRTC, rtc_paddr);
+
+ virt_base = (void __iomem *)__fix_to_virt(FIX_LNW_VRTC);
+ virt_base += rtc_paddr & ~PAGE_MASK;
+ vrtc_set_base(virt_base);
+
+ x86_platform.get_wallclock = vrtc_get_time;
+ x86_platform.set_wallclock = vrtc_set_mmss;
}
/*
@@ -287,6 +305,8 @@ void __init x86_mrst_early_setup(void)
x86_cpuinit.setup_percpu_clockev = mrst_setup_secondary_clock;
x86_platform.calibrate_tsc = mrst_calibrate_tsc;
+ x86_platform.wallclock_init = mrst_rtc_init;
+
x86_init.pci.init = pci_mrst_init;
x86_init.pci.fixup_irqs = x86_init_noop;
diff --git a/arch/x86/kernel/vrtc.c b/arch/x86/kernel/vrtc.c
new file mode 100644
index 0000000..fa1eb63
--- /dev/null
+++ b/arch/x86/kernel/vrtc.c
@@ -0,0 +1,100 @@
+/*
+ * 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 <asm/vrtc.h>
+#include <asm/time.h>
+#include <asm/fixmap.h>
+
+static unsigned char __iomem *vrtc_virt_base;
+
+void vrtc_set_base(void __iomem *base)
+{
+ vrtc_virt_base = 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(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(vrtc_cmos_write);
+
+unsigned long vrtc_get_time(void)
+{
+ u8 sec, min, hour, mday, mon;
+ u32 year;
+
+ 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);
+
+ /* vRTC YEAR reg contains the offset to 1960 */
+ year += 1960;
+
+ printk(KERN_INFO "vRTC: sec: %d min: %d hour: %d day: %d "
+ "mon: %d year: %d\n", sec, min, hour, mday, mon, year);
+
+ return mktime(year, mon, mday, hour, min, sec);
+}
+
+/* Only care about the minutes and seconds */
+int vrtc_set_mmss(unsigned long nowtime)
+{
+ int real_sec, real_min;
+ int vrtc_min;
+
+ vrtc_min = vrtc_cmos_read(RTC_MINUTES);
+
+ real_sec = nowtime % 60;
+ real_min = nowtime / 60;
+ if (((abs(real_min - vrtc_min) + 15)/30) & 1)
+ real_min += 30;
+ real_min %= 60;
+
+ vrtc_cmos_write(real_sec, RTC_SECONDS);
+ vrtc_cmos_write(real_min, RTC_MINUTES);
+ return 0;
+}
--
1.6.3.3
next prev parent reply other threads:[~2010-05-14 21:48 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-14 21:41 [PATCH 0/8] v2 Moorestown core patches for 35 merge window Jacob Pan
2010-05-14 21:41 ` [PATCH 1/8] x86/mrst/pci: return 0 for non-present pci bars Jacob Pan
2010-05-16 22:35 ` Thomas Gleixner
2010-05-17 6:33 ` [tip:x86/mrst] x86, mrst, pci: " tip-bot for Jacob Pan
2010-05-17 16:58 ` [PATCH 1/8] x86/mrst/pci: " Bjorn Helgaas
2010-05-17 17:04 ` H. Peter Anvin
2010-05-14 21:41 ` [PATCH 2/8] x86/mrst: add cpu type detection for Medfield Jacob Pan
2010-05-16 22:40 ` Thomas Gleixner
2010-05-17 16:07 ` jacob pan
2010-05-14 21:41 ` [PATCH 3/8] x86/mrst: add more timer options to include Medfield Jacob Pan
2010-05-16 22:51 ` Thomas Gleixner
2010-05-14 21:41 ` [PATCH 4/8] x86/apbt: support more timer configurations on mrst Jacob Pan
2010-05-16 22:57 ` Thomas Gleixner
2010-05-14 21:41 ` [PATCH 5/8] x86/platform: add a wallclock_init func to x86_platforms ops Jacob Pan
2010-05-16 22:43 ` Thomas Gleixner
2010-05-14 21:41 ` Jacob Pan [this message]
2010-05-16 22:44 ` [PATCH 6/8] x86/mrst: add vrtc driver which serves as a wall clock device Thomas Gleixner
2010-05-14 21:41 ` [PATCH 7/8] x86/mrst: add nop functions to x86_init mpparse functions Jacob Pan
2010-05-16 22:44 ` Thomas Gleixner
2010-05-17 6:34 ` [tip:x86/mrst] x86, mrst: " tip-bot for Jacob Pan
2010-05-14 21:41 ` [PATCH 8/8] input: do not select i8042 for x86 mid Jacob Pan
2010-05-16 22:48 ` Thomas Gleixner
2010-05-17 5:50 ` H. Peter Anvin
2010-05-17 19:44 ` jacob pan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1273873281-17489-7-git-send-email-jacob.jun.pan@linux.intel.com \
--to=jacob.jun.pan@linux.intel.com \
--cc=alan@linux.intel.com \
--cc=arjan@linux.intel.com \
--cc=feng.tang@intel.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.