timer: Provide an early timer
authorSimon Glass <sjg@chromium.org>
Wed, 24 Feb 2016 16:14:49 +0000 (09:14 -0700)
committerSimon Glass <sjg@chromium.org>
Fri, 26 Feb 2016 15:53:10 +0000 (08:53 -0700)
In some cases the timer must be accessible before driver model is active.
Examples include when using CONFIG_TRACE to trace U-Boot's execution before
driver model is set up. Enable this option to use an early timer. These
functions must be supported by your timer driver: timer_early_get_count()
and timer_early_get_rate().

Signed-off-by: Simon Glass <sjg@chromium.org>
drivers/timer/Kconfig
include/timer.h
lib/time.c

index ff65a731def3a073ba24a451263c4f39a6cc49ff..cb18f12fc99b90ee779e09c5dc37a1cfb9e0b6e4 100644 (file)
@@ -9,6 +9,16 @@ config TIMER
          will be used. The timer is usually a 32 bits free-running up
          counter. There may be no real tick, and no timer interrupt.
 
+config TIMER_EARLY
+       bool "Allow timer to be used early in U-Boot"
+       depends on TIMER
+       help
+         In some cases the timer must be accessible before driver model is
+         active. Examples include when using CONFIG_TRACE to trace U-Boot's
+         execution before driver model is set up. Enable this option to
+         use an early timer. These functions must be supported by your timer
+         driver: timer_early_get_count() and timer_early_get_rate().
+
 config ALTERA_TIMER
        bool "Altera timer support"
        depends on TIMER
index f14725cc280b5f93a8074f329b5b4641fbb69753..dcc803c392a014ae589d6e7768fcf3b39e5d42fc 100644 (file)
@@ -67,4 +67,25 @@ struct timer_dev_priv {
        unsigned long clock_rate;
 };
 
+/**
+ * timer_early_get_count() - Implement timer_get_count() before driver model
+ *
+ * If CONFIG_TIMER_EARLY is enabled, this function wil be called to return
+ * the current timer value before the proper driver model timer is ready.
+ * It should be implemented by one of the timer values. This is mostly useful
+ * for tracing.
+ */
+u64 timer_early_get_count(void);
+
+/**
+ * timer_early_get_rate() - Get the timer rate before driver model
+ *
+ * If CONFIG_TIMER_EARLY is enabled, this function wil be called to return
+ * the current timer rate in Hz before the proper driver model timer is ready.
+ * It should be implemented by one of the timer values. This is mostly useful
+ * for tracing. This corresponds to the clock_rate value in struct
+ * timer_dev_priv.
+ */
+unsigned long timer_early_get_rate(void);
+
 #endif /* _TIMER_H_ */
index e9f6861b9843773f780ec3bd278340dcb55a2a2e..f37150fddc150db21c5b147bfe8b6fffccc08498 100644 (file)
@@ -43,11 +43,17 @@ extern unsigned long __weak timer_read_counter(void);
 #ifdef CONFIG_TIMER
 ulong notrace get_tbclk(void)
 {
-       int ret;
+       if (!gd->timer) {
+#ifdef CONFIG_TIMER_EARLY
+               return timer_early_get_rate();
+#else
+               int ret;
 
-       ret = dm_timer_init();
-       if (ret)
-               return ret;
+               ret = dm_timer_init();
+               if (ret)
+                       return ret;
+#endif
+       }
 
        return timer_get_rate(gd->timer);
 }
@@ -57,9 +63,17 @@ uint64_t notrace get_ticks(void)
        u64 count;
        int ret;
 
-       ret = dm_timer_init();
-       if (ret)
-               return ret;
+       if (!gd->timer) {
+#ifdef CONFIG_TIMER_EARLY
+               return timer_early_get_count();
+#else
+               int ret;
+
+               ret = dm_timer_init();
+               if (ret)
+                       return ret;
+#endif
+       }
 
        ret = timer_get_count(gd->timer, &count);
        if (ret)