summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/linux/linux-omap2-git/beagleboard/01-gptimer_clear_isrs_on_init25
-rw-r--r--packages/linux/linux-omap2-git/beagleboard/01-make_tick_gptimer_configurable58
-rw-r--r--packages/linux/linux-omap2-git/beagleboard/02-gptimer_use_match_for_tick97
-rw-r--r--packages/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf94
-rw-r--r--packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug_to_sysrq_q110
-rw-r--r--packages/linux/linux-omap2-git/beagleboard/defconfig5
-rw-r--r--packages/linux/linux-omap2_git.bb9
7 files changed, 64 insertions, 334 deletions
diff --git a/packages/linux/linux-omap2-git/beagleboard/01-gptimer_clear_isrs_on_init b/packages/linux/linux-omap2-git/beagleboard/01-gptimer_clear_isrs_on_init
deleted file mode 100644
index 5123bafe54..0000000000
--- a/packages/linux/linux-omap2-git/beagleboard/01-gptimer_clear_isrs_on_init
+++ /dev/null
@@ -1,25 +0,0 @@
-clear
-
-From: Paul Walmsley <paul@pwsan.com>
-
-
----
-
- arch/arm/plat-omap/dmtimer.c | 4 ++++
- 1 files changed, 4 insertions(+), 0 deletions(-)
-
-diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
-index f22506a..e38a11e 100644
---- a/arch/arm/plat-omap/dmtimer.c
-+++ b/arch/arm/plat-omap/dmtimer.c
-@@ -703,6 +703,10 @@ int __init omap_dm_timer_init(void)
- timer->fclk = clk_get(NULL, clk_name);
- }
- #endif
-+ omap_dm_timer_write_status(timer, OMAP_TIMER_INT_OVERFLOW |
-+ OMAP_TIMER_INT_MATCH |
-+ OMAP_TIMER_INT_CAPTURE);
-+
- }
-
- return 0;
diff --git a/packages/linux/linux-omap2-git/beagleboard/01-make_tick_gptimer_configurable b/packages/linux/linux-omap2-git/beagleboard/01-make_tick_gptimer_configurable
new file mode 100644
index 0000000000..bcf0fa79f8
--- /dev/null
+++ b/packages/linux/linux-omap2-git/beagleboard/01-make_tick_gptimer_configurable
@@ -0,0 +1,58 @@
+OMAP2/3 GPTIMER: allow system tick GPTIMER to be configurable at build
+
+From: Paul Walmsley <paul@pwsan.com>
+
+Add Kbuild code to allow the builder to select which GPTIMER block to use
+for the Linux clockevents timer. Practical choices at this point are
+GPTIMER1 or GPTIMER12. Both of these timers are in the WKUP powerdomain,
+and so are unaffected by chip power management. GPTIMER1 can use sys_clk
+as a source, for applications where a high-resolution timer is more important
+than power management. GPTIMER12 has the special property that it has
+the secure 32kHz oscillator as its source clock, which may be less prone
+to glitches than the off-chip 32kHz oscillator.
+
+At this point, it appears that most boards are fine with GPTIMER1,
+but Beagle should use GPTIMER12.
+---
+
+ arch/arm/mach-omap2/Kconfig | 16 ++++++++++++++++
+ arch/arm/mach-omap2/timer-gp.c | 2 +-
+ 2 files changed, 17 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
+index bb6d695..0002cb6 100644
+--- a/arch/arm/mach-omap2/Kconfig
++++ b/arch/arm/mach-omap2/Kconfig
+@@ -122,3 +122,19 @@ config MACH_OMAP3EVM
+ config MACH_OMAP3_BEAGLE
+ bool "OMAP3 BEAGLE board"
+ depends on ARCH_OMAP3 && ARCH_OMAP34XX
++
++config OMAP_TICK_GPTIMER
++ int "GPTIMER used for system tick timer"
++ depends on ARCH_OMAP2 || ARCH_OMAP3
++ range 1 12
++ default 1
++ help
++ Linux uses one of the twelve on-board OMAP GPTIMER blocks to generate
++ system tick interrupts. The twelve GPTIMERs have slightly
++ different powerdomain, source clock, and security properties
++ (mostly documented in the OMAP3 TRMs) that can affect the selection
++ of which GPTIMER to use. The historical default is GPTIMER1.
++ If CONFIG_OMAP_32K_TIMER is selected, Beagle may require GPTIMER12
++ due to hardware sensitivity to glitches on the OMAP 32kHz clock
++ input.
++
+diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
+index 557603f..ec80af5 100644
+--- a/arch/arm/mach-omap2/timer-gp.c
++++ b/arch/arm/mach-omap2/timer-gp.c
+@@ -99,7 +99,7 @@ static void __init omap2_gp_clockevent_init(void)
+ {
+ u32 tick_rate;
+
+- gptimer = omap_dm_timer_request_specific(1);
++ gptimer = omap_dm_timer_request_specific(CONFIG_OMAP_TICK_GPTIMER);
+ BUG_ON(gptimer == NULL);
+
+ #if defined(CONFIG_OMAP_32K_TIMER)
diff --git a/packages/linux/linux-omap2-git/beagleboard/02-gptimer_use_match_for_tick b/packages/linux/linux-omap2-git/beagleboard/02-gptimer_use_match_for_tick
deleted file mode 100644
index 6eb6c9b477..0000000000
--- a/packages/linux/linux-omap2-git/beagleboard/02-gptimer_use_match_for_tick
+++ /dev/null
@@ -1,97 +0,0 @@
-OMAP2/3 system tick GPTIMER: use match interrupts rather than overflow interrupts
-
-From: Paul Walmsley <paul@pwsan.com>
-
-On some OMAP3 chips, GPTIMER1 will occasionally decline to interrupt
-the MPU when a timer overflow event occurs. The timer stops running;
-and TOCR is sometimes incremented; but the MPU apparently never receives
-the interrupt. This patch was an experiment in using the GPTIMER
-match interrupt to determine if it resolves the problem.
-Unfortunately, it does not; the same problem occurs with match
-interrupts; but this patch is preserved as the base for a
-match+overflow interrupt workaround used in a following patch.
----
-
- arch/arm/mach-omap2/timer-gp.c | 32 ++++++++++----------------------
- 1 files changed, 10 insertions(+), 22 deletions(-)
-
-diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
-index 557603f..51996ba 100644
---- a/arch/arm/mach-omap2/timer-gp.c
-+++ b/arch/arm/mach-omap2/timer-gp.c
-@@ -36,6 +36,8 @@
- #include <asm/mach/time.h>
- #include <asm/arch/dmtimer.h>
-
-+#define GPTIMER_MATCH_VAL 0xffff0000
-+
- static struct omap_dm_timer *gptimer;
- static struct clock_event_device clockevent_gpt;
-
-@@ -44,7 +46,7 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
- struct omap_dm_timer *gpt = (struct omap_dm_timer *)dev_id;
- struct clock_event_device *evt = &clockevent_gpt;
-
-- omap_dm_timer_write_status(gpt, OMAP_TIMER_INT_OVERFLOW);
-+ omap_dm_timer_write_status(gpt, OMAP_TIMER_INT_MATCH);
-
- evt->event_handler(evt);
- return IRQ_HANDLED;
-@@ -59,7 +61,7 @@ static struct irqaction omap2_gp_timer_irq = {
- static int omap2_gp_timer_set_next_event(unsigned long cycles,
- struct clock_event_device *evt)
- {
-- omap_dm_timer_set_load_start(gptimer, 0, 0xffffffff - cycles);
-+ omap_dm_timer_set_load_start(gptimer, 0, GPTIMER_MATCH_VAL - cycles);
-
- return 0;
- }
-@@ -67,29 +69,12 @@ static int omap2_gp_timer_set_next_event(unsigned long cycles,
- static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
- {
-- u32 period;
--
- omap_dm_timer_stop(gptimer);
--
-- switch (mode) {
-- case CLOCK_EVT_MODE_PERIODIC:
-- period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ;
-- period -= 1;
--
-- omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - period);
-- break;
-- case CLOCK_EVT_MODE_ONESHOT:
-- break;
-- case CLOCK_EVT_MODE_UNUSED:
-- case CLOCK_EVT_MODE_SHUTDOWN:
-- case CLOCK_EVT_MODE_RESUME:
-- break;
-- }
- }
-
- static struct clock_event_device clockevent_gpt = {
- .name = "gp timer",
-- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-+ .features = CLOCK_EVT_FEAT_ONESHOT,
- .shift = 32,
- .set_next_event = omap2_gp_timer_set_next_event,
- .set_mode = omap2_gp_timer_set_mode,
-@@ -111,12 +96,15 @@ static void __init omap2_gp_clockevent_init(void)
-
- omap2_gp_timer_irq.dev_id = (void *)gptimer;
- setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq);
-- omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
-+ omap_dm_timer_stop(gptimer);
-+ /* omap_dm_timer_set_load(gptimer, 0, 0);*/
-+ omap_dm_timer_set_match(gptimer, 1, GPTIMER_MATCH_VAL);
-+ omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_MATCH);
-
- clockevent_gpt.mult = div_sc(tick_rate, NSEC_PER_SEC,
- clockevent_gpt.shift);
- clockevent_gpt.max_delta_ns =
-- clockevent_delta2ns(0xffffffff, &clockevent_gpt);
-+ clockevent_delta2ns(GPTIMER_MATCH_VAL, &clockevent_gpt);
- clockevent_gpt.min_delta_ns =
- clockevent_delta2ns(1, &clockevent_gpt);
-
diff --git a/packages/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf b/packages/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf
deleted file mode 100644
index 3de6e05042..0000000000
--- a/packages/linux/linux-omap2-git/beagleboard/03-gptimer_match_plus_ovf
+++ /dev/null
@@ -1,94 +0,0 @@
-OMAP2/3 system tick GPTIMER: use overflow interrupts to detect missing match interrupts
-
-From: Paul Walmsley <paul@pwsan.com>
-
-GPTIMER1 on some OMAP3 chips occasionally misses match conditions
-between the timer counter and the target register value, and does not
-interrupt to the MPU. This patch adds another line of defense by
-setting the timer to generate an overflow interrupt 0.5 seconds after the
-timer passes the original comparison value.
-
-If interrupts are masked for a long period of time, one would expect
-both a match and an overflow interrupt to be logged. This is considered
-a normal condition. However, if only an overflow interrupt is logged,
-this is considered evidence of a hardware bug and the kernel will issue
-a warning.
-
-This workaround is unlikely to be 100% effective, since GPTIMER1 has
-also been observed to lose overflow interrupts occasionally. It is
-hoped that the probability of losing both will be significantly lower
-than the probability of losing either one.
----
-
- arch/arm/mach-omap2/timer-gp.c | 36 ++++++++++++++++++++++++++++++++----
- 1 files changed, 32 insertions(+), 4 deletions(-)
-
-diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
-index 51996ba..ce5c2b4 100644
---- a/arch/arm/mach-omap2/timer-gp.c
-+++ b/arch/arm/mach-omap2/timer-gp.c
-@@ -36,17 +36,43 @@
- #include <asm/mach/time.h>
- #include <asm/arch/dmtimer.h>
-
--#define GPTIMER_MATCH_VAL 0xffff0000
-+/*
-+ * The number of timer ticks to delay will be subtracted from
-+ * GPTIMER_MATCH_VAL before loading into the timer. So GPTIMER_MATCH_VAL
-+ * constrains the longest delay that can be generated with the timer.
-+ * Since the current code uses overflow interrupts as protection against
-+ * missed comparison interrupts, this value should also be sufficiently
-+ * large such that there is not an excessively long delay between ticks
-+ * if the comparison interrupt fails to arrive. The 0xfffff800 value
-+ * below results in a half-second delay in such a case when using
-+ * the 32kHz timer as source.
-+ */
-+#define GPTIMER_MATCH_VAL (0xffffffff - (32768/2))
-
- static struct omap_dm_timer *gptimer;
- static struct clock_event_device clockevent_gpt;
-
-+static u32 last_load;
-+
- static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
- {
- struct omap_dm_timer *gpt = (struct omap_dm_timer *)dev_id;
- struct clock_event_device *evt = &clockevent_gpt;
--
-- omap_dm_timer_write_status(gpt, OMAP_TIMER_INT_MATCH);
-+ u32 v;
-+
-+ v = omap_dm_timer_read_status(gpt);
-+ if ((v & OMAP_TIMER_INT_OVERFLOW) && !(v & OMAP_TIMER_INT_MATCH)) {
-+ /*
-+ * Should never happen. Current belief is that this is
-+ * due to a hardware bug in the GPTIMER block on some
-+ * OMAP3 revisions.
-+ */
-+ pr_err("*** GPTIMER missed match interrupt! last load: %08x\n",
-+ last_load);
-+ WARN_ON(1);
-+ }
-+
-+ omap_dm_timer_write_status(gpt, v);
-
- evt->event_handler(evt);
- return IRQ_HANDLED;
-@@ -61,6 +87,7 @@ static struct irqaction omap2_gp_timer_irq = {
- static int omap2_gp_timer_set_next_event(unsigned long cycles,
- struct clock_event_device *evt)
- {
-+ last_load = GPTIMER_MATCH_VAL - cycles;
- omap_dm_timer_set_load_start(gptimer, 0, GPTIMER_MATCH_VAL - cycles);
-
- return 0;
-@@ -99,7 +126,8 @@ static void __init omap2_gp_clockevent_init(void)
- omap_dm_timer_stop(gptimer);
- /* omap_dm_timer_set_load(gptimer, 0, 0);*/
- omap_dm_timer_set_match(gptimer, 1, GPTIMER_MATCH_VAL);
-- omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_MATCH);
-+ omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_MATCH |
-+ OMAP_TIMER_INT_OVERFLOW);
-
- clockevent_gpt.mult = div_sc(tick_rate, NSEC_PER_SEC,
- clockevent_gpt.shift);
diff --git a/packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug_to_sysrq_q b/packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug_to_sysrq_q
deleted file mode 100644
index aa9f09811a..0000000000
--- a/packages/linux/linux-omap2-git/beagleboard/04-gptimer_add_debug_to_sysrq_q
+++ /dev/null
@@ -1,110 +0,0 @@
-Add extra debug for the q_d_w_o() when work fn is already active.
-
-From: Paul Walmsley <paul@pwsan.com>
-
-
----
-
- arch/arm/mach-omap2/timer-gp.c | 3 ++-
- arch/arm/plat-omap/dmtimer.c | 20 ++++++++++++++++++++
- include/asm-arm/arch-omap/dmtimer.h | 1 +
- kernel/time/timer_list.c | 8 ++++++++
- 4 files changed, 31 insertions(+), 1 deletions(-)
-
-diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
-index ce5c2b4..e3ed368 100644
---- a/arch/arm/mach-omap2/timer-gp.c
-+++ b/arch/arm/mach-omap2/timer-gp.c
-@@ -50,6 +50,7 @@
- #define GPTIMER_MATCH_VAL (0xffffffff - (32768/2))
-
- static struct omap_dm_timer *gptimer;
-+struct omap_dm_timer *gptimer_pub;
- static struct clock_event_device clockevent_gpt;
-
- static u32 last_load;
-@@ -111,7 +112,7 @@ static void __init omap2_gp_clockevent_init(void)
- {
- u32 tick_rate;
-
-- gptimer = omap_dm_timer_request_specific(1);
-+ gptimer = gptimer_pub = omap_dm_timer_request_specific(1);
- BUG_ON(gptimer == NULL);
-
- #if defined(CONFIG_OMAP_32K_TIMER)
-diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
-index e38a11e..b10f8ac 100644
---- a/arch/arm/plat-omap/dmtimer.c
-+++ b/arch/arm/plat-omap/dmtimer.c
-@@ -614,6 +614,26 @@ void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
- omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value);
- }
-
-+void omap_dm_timer_dump_int_enable(struct omap_dm_timer *timer)
-+{
-+ u32 l;
-+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
-+ pr_err("GPT TCRR: %08x\n", l);
-+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_MATCH_REG);
-+ pr_err("GPT TMAT: %08x\n", l);
-+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);
-+ pr_err("GPT TISR: %08x\n", l);
-+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_INT_EN_REG);
-+ pr_err("GPT TIER: %08x\n", l);
-+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
-+ pr_err("GPT TCLR: %08x\n", l);
-+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_TICK_INT_MASK_SET_REG);
-+ pr_err("GPT TOCR: %08x\n", l);
-+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_TICK_INT_MASK_COUNT_REG);
-+ pr_err("GPT TOWR: %08x\n", l);
-+}
-+
-+
- unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
- {
- unsigned int l;
-diff --git a/include/asm-arm/arch-omap/dmtimer.h b/include/asm-arm/arch-omap/dmtimer.h
-index 02b29e8..a8123e9 100644
---- a/include/asm-arm/arch-omap/dmtimer.h
-+++ b/include/asm-arm/arch-omap/dmtimer.h
-@@ -73,6 +73,7 @@ void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
-
- void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
-
-+void omap_dm_timer_dump_int_enable(struct omap_dm_timer *timer);
- unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
- void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
- unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer);
-diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
-index a40e20f..452eab7 100644
---- a/kernel/time/timer_list.c
-+++ b/kernel/time/timer_list.c
-@@ -18,6 +18,8 @@
- #include <linux/kallsyms.h>
- #include <linux/tick.h>
-
-+#include <asm/arch/dmtimer.h>
-+
- #include <asm/uaccess.h>
-
- typedef void (*print_fn_t)(struct seq_file *m, unsigned int *classes);
-@@ -239,6 +241,8 @@ static void timer_list_show_tickdevices(struct seq_file *m)
- static void timer_list_show_tickdevices(struct seq_file *m) { }
- #endif
-
-+extern struct omap_dm_timer *gptimer_pub;
-+
- static int timer_list_show(struct seq_file *m, void *v)
- {
- u64 now = ktime_to_ns(ktime_get());
-@@ -254,6 +258,10 @@ static int timer_list_show(struct seq_file *m, void *v)
- SEQ_printf(m, "\n");
- timer_list_show_tickdevices(m);
-
-+ SEQ_printf(m, "\n");
-+
-+ omap_dm_timer_dump_int_enable(gptimer_pub);
-+
- return 0;
- }
-
diff --git a/packages/linux/linux-omap2-git/beagleboard/defconfig b/packages/linux/linux-omap2-git/beagleboard/defconfig
index d01d473ed5..c07d0ab5e2 100644
--- a/packages/linux/linux-omap2-git/beagleboard/defconfig
+++ b/packages/linux/linux-omap2-git/beagleboard/defconfig
@@ -187,8 +187,8 @@ CONFIG_OMAP_BOOT_REASON=y
CONFIG_OMAP_MCBSP=y
# CONFIG_OMAP_MMU_FWK is not set
# CONFIG_OMAP_MBOX_FWK is not set
-CONFIG_OMAP_MPU_TIMER=y
-# CONFIG_OMAP_32K_TIMER is not set
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
CONFIG_OMAP_DM_TIMER=y
# CONFIG_OMAP_LL_DEBUG_UART1 is not set
# CONFIG_OMAP_LL_DEBUG_UART2 is not set
@@ -203,6 +203,7 @@ CONFIG_ARCH_OMAP3430=y
# CONFIG_MACH_OMAP_3430SDP is not set
# CONFIG_MACH_OMAP3EVM is not set
CONFIG_MACH_OMAP3_BEAGLE=y
+CONFIG_OMAP_TICK_GPTIMER=12
#
# Boot options
diff --git a/packages/linux/linux-omap2_git.bb b/packages/linux/linux-omap2_git.bb
index 4008102f09..5749d4fc0c 100644
--- a/packages/linux/linux-omap2_git.bb
+++ b/packages/linux/linux-omap2_git.bb
@@ -6,9 +6,9 @@ SRCREV = "d6daf8d8cc5ccf90247def5551ee9c3e8555e848"
PV = "2.6.26"
#PV = "2.6.26+2.6.27-rc1+${PR}+git${SRCREV}"
-PR = "r58"
+PR = "r59"
-SRC_URI = "git://source.mvista.com/git/linux-omap-2.6.git;protocol=git \
+SRC_URI = "git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git;protocol=git \
file://defconfig"
SRC_URI_append_beagleboard = " file://no-harry-potter.diff;patch=1 \
@@ -35,10 +35,7 @@ SRC_URI_append_beagleboard = " file://no-harry-potter.diff;patch=1 \
file://mru-clocks3.diff;patch=1 \
file://4bitmmc.diff;patch=1 \
file://no-cortex-deadlock.patch;patch=1 \
- file://01-gptimer_clear_isrs_on_init;patch=1 \
- file://02-gptimer_use_match_for_tick;patch=1 \
- file://03-gptimer_match_plus_ovf;patch=1 \
- file://04-gptimer_add_debug_to_sysrq_q;patch=1 \
+ file://01-make_tick_gptimer_configurable;patch=1 \
file://read_die_ids.patch;patch=1 \
"