Ive worked up a new clocksource driver for my SC-1100 based board,
which has a buggy TSC, but also an on-chip hires timer.
Ive just applied the patch to 17-rc3-mm1, but my Kconfig & Makefile
hacks arent working correctly (They seemed to work right on rc1, but ..)
1. It doesnt build. It is on in the .config, but this doesnt trigger a make
[jimc@harpo hrt2]$ grep 200 .config
# Mon May 1 23:16:51 2006
CONFIG_SCx200HR_TIMER=m
CONFIG_SCx200=m
CONFIG_BLK_DEV_SC1200=m
[jimc@harpo hrt2]$ more drivers/clocksource/Makefile
obj-$(CONFIG_X86_CYCLONE_TIMER) += cyclone.o
obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o
obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o
2 - arch/i386/Kconfig doesnt seem like the right place for the config entry.
When I tried to move it to drivers/clocksource/Kconfig,
I got errs about SCx200 not being defined (ie the dependency)
menu "Processor type and features"
config SCx200HR_TIMER
tristate "NatSemi SCx200 27MHz High-Resolution Timer Support"
help
Some of the AMD (formerly National Semiconductor) Geode
processors, notably the SC1100, suffer from a buggy time
stamp counter which causes them to lose time when the
processor is sleeping. Enable this option to use the
on-board 27Mz high-resolution timer to keep time instead.
depends on (SCx200)
default n
Later in the same file, I have following (note the select - reverse
dependency)
config SCx200
tristate "NatSemi SCx200 support"
depends on !X86_VOYAGER
select SCx200HR_TIMER
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.
3. If I force-build it manually, at least something happens.
[jimc@harpo hrt2]$ make drivers/clocksource/scx200_hrt.ko
CHK include/linux/version.h
CC [M] drivers/clocksource/scx200_hrt.o
drivers/clocksource/scx200_hrt.c:70: warning: left shift count >= width
of type
MODPOST
WARNING: "scx200_cb_base" [drivers/clocksource/scx200_hrt.ko] undefined!
CC drivers/clocksource/scx200_hrt.mod.o
LD [M] drivers/clocksource/scx200_hrt.ko
4. separately, what does the 1st warning mean in this code ?
57 #ifndef CLKSRC_MASK
58 /* move to clocksource.h ?? */
59 #define CLKSRC_MASK(bits) (cycle_t)((1<<bits)-1)
60 #endif
61
62 #define HRT_MASK CLKSRC_MASK(32)
66 static struct clocksource cs_hrt = {
67 .name = "scx200_hrt",
68 .rating = 250,
69 .read = read_hrt,
70 .mask = HRT_MASK,
yes, mask is a cycle_t, a u64.
I have a suspicion that the build problems are interrelated, and Im just
missing it.
Can any wise and generous soul set me straight ?
Oh, and heres the patch.
tia
jimc
diff -ruNp -X dontdiff -X exclude-diffs mm3-clk-renames/arch/i386/Kconfig hrt2/arch/i386/Kconfig
--- mm3-clk-renames/arch/i386/Kconfig 2006-04-18 07:49:49.000000000 -0400
+++ hrt2/arch/i386/Kconfig 2006-04-23 11:00:28.000000000 -0400
@@ -57,6 +57,17 @@ source "init/Kconfig"
menu "Processor type and features"
+config SCx200HR_TIMER
+ tristate "NatSemi SCx200 27MHz High-Resolution Timer Support"
+ help
+ Some of the AMD (formerly National Semiconductor) Geode
+ processors, notably the SC1100, suffer from a buggy time
+ stamp counter which causes them to lose time when the
+ processor is sleeping. Enable this option to use the
+ on-board 27Mz high-resolution timer to keep time instead.
+ depends on (SCx200)
+ default n
+
config SMP
bool "Symmetric multi-processing support"
---help---
@@ -1048,6 +1059,7 @@ source "drivers/mca/Kconfig"
config SCx200
tristate "NatSemi SCx200 support"
depends on !X86_VOYAGER
+ select SCx200HR_TIMER
help
This provides basic support for the National Semiconductor SCx200
processor. Right now this is just a driver for the GPIO pins.
diff -ruNp -X dontdiff -X exclude-diffs mm3-clk-renames/drivers/clocksource/Makefile hrt2/drivers/clocksource/Makefile
--- mm3-clk-renames/drivers/clocksource/Makefile 2006-04-18 07:50:20.000000000 -0400
+++ hrt2/drivers/clocksource/Makefile 2006-04-23 11:00:28.000000000 -0400
@@ -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 mm3-clk-renames/drivers/clocksource/scx200_hrt.c hrt2/drivers/clocksource/scx200_hrt.c
--- mm3-clk-renames/drivers/clocksource/scx200_hrt.c 1969-12-31 19:00:00.000000000 -0500
+++ hrt2/drivers/clocksource/scx200_hrt.c 2006-04-24 08:42:06.000000000 -0400
@@ -0,0 +1,110 @@
+/*
+ * 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);
+MODULE_PARM_DESC(mhz27, "count at 27 MHz (default is 1 MHz)\n");
+
+/* High-resolution timer configuration address
+ NB: HR_TM* symbols match corresponding TM* in the datasheet
+ HRT_* are clocksource-related constants for this driver
+*/
+#define SCx200_TMCNFG_OFFSET (SCx200_TIMER_OFFSET + 5)
+
+/* Set this bit to disable the 27 MHz input clock */
+#define HR_TM27MPD (1 << 2)
+
+/* Set this bit to count at 27MHz, clear to count at 1MHz */
+#define HR_TMCLKSEL (1 << 1)
+
+/* Set this bit to enable the high-resolution timer interrupt */
+#define HR_TMEN (1 << 0)
+
+/* The timer frequency; must be 27_000_000 or 1_000_000, depending upon
+ HR_TMCLKSEL bit-value actually used */
+#define HRT_FREQ_1 1000000
+#define HRT_FREQ_27 27000000
+
+static cycle_t read_hrt(void)
+{
+ /* Read the timer value */
+ return (cycle_t) inl(scx200_cb_base + SCx200_TIMER_OFFSET);
+}
+
+#ifndef CLKSRC_MASK
+/* move to clocksource.h ?? */
+#define CLKSRC_MASK(bits) (cycle_t)((1<<bits)-1)
+#endif
+
+#define HRT_MASK CLKSRC_MASK(32)
+#define HRT_SHIFT_1 22
+#define HRT_SHIFT_27 24
+
+static struct clocksource cs_hrt = {
+ .name = "scx200_hrt",
+ .rating = 250,
+ .read = read_hrt,
+ .mask = HRT_MASK,
+ .is_continuous = 1,
+ /* mult, shift are set during init */
+};
+
+static int __init init_hrt_clocksource(void)
+{
+ /* Make sure the configuration block is present */
+ 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;
+ }
+
+ /* Configure the timer: 1 or 27 MHz, no interrupt */
+ outb((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_27, HRT_SHIFT_27);
+ } else {
+ cs_hrt.shift = HRT_SHIFT_1;
+ cs_hrt.mult = clocksource_hz2mult(HRT_FREQ_1, HRT_SHIFT_1);
+ }
+ printk(KERN_INFO "enabling scx200 high-res timer (%d MHz)\n",
+ mhz27 ? 27 : 1);
+
+ return clocksource_register(&cs_hrt);
+}
+
+module_init(init_hrt_clocksource);
+
+MODULE_AUTHOR("Jim Cromie <jim.cromie@xxxxxxxxx>");
+MODULE_DESCRIPTION("SCx200 HiRes Timer for Generic Timekeeping System");
+MODULE_LICENSE("GPL");
diff -ruNp -X dontdiff -X exclude-diffs mm3-clk-renames/localversion hrt2/localversion
--- mm3-clk-renames/localversion 1969-12-31 19:00:00.000000000 -0500
+++ hrt2/localversion 2006-04-23 11:00:28.000000000 -0400
@@ -0,0 +1 @@
+-hrt
Binary files mm3-clk-renames/scripts/genksyms/genksyms and hrt2/scripts/genksyms/genksyms differ