[patch -mm] generic-time: add clocksource based upon scx200's 27 MHz hires timer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





This patch adds a clocksource driver for the Generic Time Subsystem
which uses the Hi-Res Timer hardware on Geode SCx200 integrated CPU.
against 17-rc3-mm1 + clocksource-mask patch which has since been added
to the generic-time patch-set, C2 rev.

It is a rework of previously sent patch:
 http://marc.theaimsgroup.com/?l=linux-kernel&m=114588665115350&w=2

Ive been testing it for most of the time since I 1st posted, Ive been
unable to replicate the hang-on-boot on a fresh tree.  I'm blaming it
on a bad build tree, and other developer errors.

New patch is also compile tested on rc4-mm1, and previously tested
with allmod, allno + scx200-* builtins and loadable modules.  Ive had
no response to my call-for-testers message to soekris-tech@, perhaps
I'll have more success getting testers once its in -mm.


Mod-Params

- ppm clock tweak

Allows tuning clocksource to match XTAL freq.  arg is unclamped, so
you could adjust the clock by + 1MHz, sensible if youve got a
different XTAL, not great otherwise.  I used this to verify that ntpq
-pcrv's frequency=<number> changed in relation to the ppm=<complement>
I started the test with.

The modparam has some value for rough adjustment of a free-running
clocksource, but since XTALs (sample 1) have manufacturing tolerance
and temp-stability of +-30ppm and +-50ppm respectively, you cannot
expect to correct for temps, but you can normalize error for your
crystal.

This mod-param can only be set during initialization, and the module
cannot be unloaded, so changing this param requires a reboot; it is
not a mechanism to track corrections, ntpd is far better for that.

- mhz27

This flag determines count speed, hence timer rollover rate.  At
27mhz, timer rolls every 2.6 min.  I almost dumped this option, and
hardcoded the timer for 27mhz operation, but that loses some
flexibility.

Its not clear to me why the circuit is desiged for a 27 MHz crystal
instead of an on-chip derived clock, but I suspect theres some
reason for it.  TV/video ?


wrt the Todos:
- kconfig entry now immediately after SCx200
- module on built-in (no)
- platform_driver (irrelevant?)

Please consider for -mmNext

Im trying to do the thunderbird shuffle here, perhaps it will work.
will resend final version w fixes as attachment if necessary.

thanks

---

Add new GTOD-clocksource driver for the High Resolution Timer on the
Geode SC-1100 and family.  Driver is dependent on scx200.  When
scx200_hrt is loaded, GTOD chooses it over the unstable and de-rated
TSC, unless idle=poll is given on boot-line (the workaround)

Signed-off-by:  Jim Cromie <[email protected]>


$ diffstat time-clksrc-add-scx200-hrt.patch
arch/i386/Kconfig                |   24 ++++++---
drivers/clocksource/Makefile     |    5 +
drivers/clocksource/scx200_hrt.c |  101 +++++++++++++++++++++++++++++++++++++++
localversion                     |    1 (trimmed from patch)
localversion-clk                 |    1
5 files changed, 122 insertions(+), 10 deletions(-)

---




diff -ruNp -X dontdiff -X exclude-diffs clksrc-mask/arch/i386/Kconfig hrt-tune/arch/i386/Kconfig
--- clksrc-mask/arch/i386/Kconfig	2006-05-03 06:29:48.000000000 -0600
+++ hrt-tune/arch/i386/Kconfig	2006-05-18 11:24:02.000000000 -0600
@@ -1049,13 +1049,23 @@ config SCx200
	tristate "NatSemi SCx200 support"
	depends on !X86_VOYAGER
	help
-	  This provides basic support for the National Semiconductor SCx200
-	  processor.  Right now this is just a driver for the GPIO pins.
-
-	  If you don't know what to do here, say N.
-
-	  This support is also available as a module.  If compiled as a
-	  module, it will be called scx200.
+	  This provides basic support for National Semiconductor's
+	  (now AMD's) Geode processors.  The driver probes for the
+	  PCI-IDs of several on-chip devices, so its a good dependency
+	  for other scx200_* drivers.
+
+	  If compiled as a module, the driver is named scx200.
+
+config SCx200HR_TIMER
+	tristate "NatSemi SCx200 27MHz High-Resolution Timer Support"
+	depends on SCx200 && GENERIC_TIME
+	default y
+	help
+	  This driver provides a clocksource built upon the on-chip
+	  27MHz high-resolution timer.  Its also a workaround for
+	  NSC Geode SC-1100's buggy TSC, which loses time when the
+	  processor goes idle (as is done by the scheduler).  The
+	  other workaround is idle=poll boot option.

config K8_NB
	def_bool y
diff -ruNp -X dontdiff -X exclude-diffs clksrc-mask/drivers/clocksource/Makefile hrt-tune/drivers/clocksource/Makefile
--- clksrc-mask/drivers/clocksource/Makefile	2006-05-03 06:29:58.000000000 -0600
+++ hrt-tune/drivers/clocksource/Makefile	2006-05-14 01:12:54.000000000 -0600
@@ -1,2 +1,3 @@
-obj-$(CONFIG_X86_CYCLONE_TIMER) += cyclone.o
-obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o
+obj-$(CONFIG_X86_CYCLONE_TIMER)	+= cyclone.o
+obj-$(CONFIG_X86_PM_TIMER)	+= acpi_pm.o
+obj-$(CONFIG_SCx200HR_TIMER)	+= scx200_hrt.o
diff -ruNp -X dontdiff -X exclude-diffs clksrc-mask/drivers/clocksource/scx200_hrt.c hrt-tune/drivers/clocksource/scx200_hrt.c
--- clksrc-mask/drivers/clocksource/scx200_hrt.c	1969-12-31 17:00:00.000000000 -0700
+++ hrt-tune/drivers/clocksource/scx200_hrt.c	2006-05-18 09:47:25.000000000 -0600
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2006 Jim Cromie
+ *
+ * This is a clocksource driver for the Geode SCx200's 1 or 27 MHz
+ * high-resolution timer.  The Geode SC-1100 (at least) has a buggy
+ * time stamp counter (TSC), which loses time unless 'idle=poll' is
+ * given as a boot-arg. In its absence, the Generic Timekeeping code
+ * will detect and de-rate the bad TSC, allowing this timer to take
+ * over timekeeping duties.
+ *
+ * Based on work by John Stultz and Ted Phelps (in a 2.6.12-rc6 patch)
+ *
+ * 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/clocksource.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/scx200.h>
+
+#define NAME "scx200_hrt"
+
+static int mhz27;
+module_param(mhz27, int, 0);	/* load time only */
+MODULE_PARM_DESC(mhz27, "count at 27.0 MHz (default is 1.0 MHz)\n");
+
+static int ppm;
+module_param(ppm, int, 0);	/* load time only */
+MODULE_PARM_DESC(ppm, "+-adjust to actual XO freq (ppm)\n");
+
+/* HiRes Timer configuration register address */
+#define SCx200_TMCNFG_OFFSET (SCx200_TIMER_OFFSET + 5)
+
+/* and config settings */
+#define HR_TMEN (1 << 0)	/* timer interrupt enable */
+#define HR_TMCLKSEL (1 << 1)	/* 1|0 counts at 27|1 MHz */
+#define HR_TM27MPD (1 << 2)	/* 1 turns off input clock (power-down) */
+
+/* The base timer frequency, * 27 if selected */
+#define HRT_FREQ   1000000
+
+static cycle_t read_hrt(void)
+{
+	/* Read the timer value */
+	return (cycle_t) inl(scx200_cb_base + SCx200_TIMER_OFFSET);
+}
+
+#define HRT_SHIFT_1	22
+#define HRT_SHIFT_27	26
+
+static struct clocksource cs_hrt = {
+	.name		= "scx200_hrt",
+	.rating		= 250,
+	.read		= read_hrt,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.is_continuous	= 1,
+	/* mult, shift are set based on mhz27 flag */
+};
+
+static int __init init_hrt_clocksource(void)
+{
+        /* Make sure scx200 has initd the configuration block */
+	if (!scx200_cb_present())
+		return -ENODEV;
+
+	/* Reserve the timer's ISA io-region for ourselves */
+	if (!request_region(scx200_cb_base + SCx200_TIMER_OFFSET,
+			    SCx200_TIMER_SIZE,
+			    "NatSemi SCx200 High-Resolution Timer")) {
+		printk(KERN_WARNING NAME ": unable to lock timer region\n");
+		return -ENODEV;
+	}
+
+	/* write timer config */
+	outb(HR_TMEN | (mhz27) ? HR_TMCLKSEL : 0,
+	     scx200_cb_base + SCx200_TMCNFG_OFFSET);
+	
+	if (mhz27) {
+		cs_hrt.shift = HRT_SHIFT_27;
+		cs_hrt.mult = clocksource_hz2mult((HRT_FREQ + ppm) * 27,
+						  cs_hrt.shift);
+	} else {
+		cs_hrt.shift = HRT_SHIFT_1;
+		cs_hrt.mult = clocksource_hz2mult(HRT_FREQ + ppm,
+						  cs_hrt.shift);
+	}
+	printk(KERN_INFO "enabling scx200 high-res timer (%s MHz +%d ppm)\n",
+	       mhz27 ? "27":"1", ppm);
+
+	return clocksource_register(&cs_hrt);
+}
+
+module_init(init_hrt_clocksource);
+
+MODULE_AUTHOR("Jim Cromie <[email protected]>");
+MODULE_DESCRIPTION("clocksource on SCx200 HiRes Timer");
+MODULE_LICENSE("GPL");


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux