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