1 /* 2 * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw> 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <errno.h> 10 #include <timer.h> 11 #include <os.h> 12 13 #define SANDBOX_TIMER_RATE 1000000 14 15 /* system timer offset in ms */ 16 static unsigned long sandbox_timer_offset; 17 18 void sandbox_timer_add_offset(unsigned long offset) 19 { 20 sandbox_timer_offset += offset; 21 } 22 23 u64 notrace timer_early_get_count(void) 24 { 25 return os_get_nsec() / 1000 + sandbox_timer_offset * 1000; 26 } 27 28 unsigned long notrace timer_early_get_rate(void) 29 { 30 return SANDBOX_TIMER_RATE; 31 } 32 33 static notrace int sandbox_timer_get_count(struct udevice *dev, u64 *count) 34 { 35 *count = timer_early_get_count(); 36 37 return 0; 38 } 39 40 static int sandbox_timer_probe(struct udevice *dev) 41 { 42 struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); 43 44 if (!uc_priv->clock_rate) 45 uc_priv->clock_rate = SANDBOX_TIMER_RATE; 46 47 return 0; 48 } 49 50 static const struct timer_ops sandbox_timer_ops = { 51 .get_count = sandbox_timer_get_count, 52 }; 53 54 static const struct udevice_id sandbox_timer_ids[] = { 55 { .compatible = "sandbox,timer" }, 56 { } 57 }; 58 59 U_BOOT_DRIVER(sandbox_timer) = { 60 .name = "sandbox_timer", 61 .id = UCLASS_TIMER, 62 .of_match = sandbox_timer_ids, 63 .probe = sandbox_timer_probe, 64 .ops = &sandbox_timer_ops, 65 .flags = DM_FLAG_PRE_RELOC, 66 }; 67 68 /* This is here in case we don't have a device tree */ 69 U_BOOT_DEVICE(sandbox_timer_non_fdt) = { 70 .name = "sandbox_timer", 71 }; 72