diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index ff65a731def3a073ba24a451263c4f39a6cc49ff..cb18f12fc99b90ee779e09c5dc37a1cfb9e0b6e4 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -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
diff --git a/include/timer.h b/include/timer.h
index f14725cc280b5f93a8074f329b5b4641fbb69753..dcc803c392a014ae589d6e7768fcf3b39e5d42fc 100644
--- a/include/timer.h
+++ b/include/timer.h
@@ -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_ */
diff --git a/lib/time.c b/lib/time.c
index e9f6861b9843773f780ec3bd278340dcb55a2a2e..f37150fddc150db21c5b147bfe8b6fffccc08498 100644
--- a/lib/time.c
+++ b/lib/time.c
@@ -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)