sides = <4>;
        };
 
+       timer {
+               compatible = "sandbox,timer";
+       };
+
        tpm {
                compatible = "google,sandbox-tpm";
        };
 
 {
 }
 
+#ifndef CONFIG_TIMER
 /* system timer offset in ms */
 static unsigned long sandbox_timer_offset;
 
 {
        return os_get_nsec() / 1000 + sandbox_timer_offset * 1000;
 }
+#endif
 
 int dram_init(void)
 {
 
 CONFIG_SOUND=y
 CONFIG_SOUND_SANDBOX=y
 CONFIG_SANDBOX_SPI=y
+CONFIG_TIMER=y
+CONFIG_SANDBOX_TIMER=y
 CONFIG_TPM_TIS_SANDBOX=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
 
--- /dev/null
+Sandbox timer
+
+The sandbox timer device is an emulated device which gets time from
+host os.
+
+Required properties:
+  compatible: "sandbox,timer"
 
          Select this to enable an timer for Altera devices. Please find
          details on the "Embedded Peripherals IP User Guide" of Altera.
 
+config SANDBOX_TIMER
+       bool "Sandbox Timer support"
+       depends on SANDBOX && TIMER
+       help
+         Select this to enable an emulated timer for sandbox. It gets
+         time from host os.
+
 endmenu
 
 
 obj-$(CONFIG_TIMER)            += timer-uclass.o
 obj-$(CONFIG_ALTERA_TIMER)     += altera_timer.o
+obj-$(CONFIG_SANDBOX_TIMER)    += sandbox_timer.o
 
--- /dev/null
+/*
+ * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <timer.h>
+#include <os.h>
+
+/* system timer offset in ms */
+static unsigned long sandbox_timer_offset;
+
+void sandbox_timer_add_offset(unsigned long offset)
+{
+       sandbox_timer_offset += offset;
+}
+
+static int sandbox_timer_get_count(struct udevice *dev, unsigned long *count)
+{
+       *count = os_get_nsec() / 1000 + sandbox_timer_offset * 1000;
+
+       return 0;
+}
+
+static int sandbox_timer_probe(struct udevice *dev)
+{
+       struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+       uc_priv->clock_rate = 1000000;
+
+       return 0;
+}
+
+static const struct timer_ops sandbox_timer_ops = {
+       .get_count = sandbox_timer_get_count,
+};
+
+static const struct udevice_id sandbox_timer_ids[] = {
+       { .compatible = "sandbox,timer" },
+       { }
+};
+
+U_BOOT_DRIVER(sandbox_timer) = {
+       .name   = "sandbox_timer",
+       .id     = UCLASS_TIMER,
+       .of_match = sandbox_timer_ids,
+       .probe = sandbox_timer_probe,
+       .ops    = &sandbox_timer_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
 
 #define CONFIG_IO_TRACE
 #define CONFIG_CMD_IOTRACE
 
+#ifndef CONFIG_TIMER
 #define CONFIG_SYS_TIMER_RATE          1000000
+#endif
 
 #define CONFIG_SYS_STDIO_DEREGISTER
 
 
 obj-$(CONFIG_DM_USB) += usb.o
 obj-$(CONFIG_DM_PMIC) += pmic.o
 obj-$(CONFIG_DM_REGULATOR) += regulator.o
+obj-$(CONFIG_TIMER) += timer.o
 obj-$(CONFIG_ADC) += adc.o
 endif
 
--- /dev/null
+/*
+ * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <timer.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Basic test of the timer uclass.
+ */
+static int dm_test_timer_base(struct unit_test_state *uts)
+{
+       struct udevice *dev;
+
+       ut_assertok(uclass_get_device(UCLASS_TIMER, 0, &dev));
+       ut_asserteq(1000000, timer_get_rate(dev));
+
+       return 0;
+}
+DM_TEST(dm_test_timer_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);