1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
29961a0b6SThomas Chou /*
39961a0b6SThomas Chou * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
49961a0b6SThomas Chou */
59961a0b6SThomas Chou
69961a0b6SThomas Chou #include <common.h>
79961a0b6SThomas Chou #include <dm.h>
89961a0b6SThomas Chou #include <errno.h>
99961a0b6SThomas Chou #include <timer.h>
109961a0b6SThomas Chou #include <os.h>
119961a0b6SThomas Chou
1201476eafSSimon Glass #define SANDBOX_TIMER_RATE 1000000
1301476eafSSimon Glass
149961a0b6SThomas Chou /* system timer offset in ms */
159961a0b6SThomas Chou static unsigned long sandbox_timer_offset;
169961a0b6SThomas Chou
sandbox_timer_add_offset(unsigned long offset)179961a0b6SThomas Chou void sandbox_timer_add_offset(unsigned long offset)
189961a0b6SThomas Chou {
199961a0b6SThomas Chou sandbox_timer_offset += offset;
209961a0b6SThomas Chou }
219961a0b6SThomas Chou
timer_early_get_count(void)2201476eafSSimon Glass u64 notrace timer_early_get_count(void)
239961a0b6SThomas Chou {
2401476eafSSimon Glass return os_get_nsec() / 1000 + sandbox_timer_offset * 1000;
2501476eafSSimon Glass }
2601476eafSSimon Glass
timer_early_get_rate(void)2701476eafSSimon Glass unsigned long notrace timer_early_get_rate(void)
2801476eafSSimon Glass {
2901476eafSSimon Glass return SANDBOX_TIMER_RATE;
3001476eafSSimon Glass }
3101476eafSSimon Glass
sandbox_timer_get_count(struct udevice * dev,u64 * count)3201476eafSSimon Glass static notrace int sandbox_timer_get_count(struct udevice *dev, u64 *count)
3301476eafSSimon Glass {
3401476eafSSimon Glass *count = timer_early_get_count();
359961a0b6SThomas Chou
369961a0b6SThomas Chou return 0;
379961a0b6SThomas Chou }
389961a0b6SThomas Chou
sandbox_timer_probe(struct udevice * dev)399961a0b6SThomas Chou static int sandbox_timer_probe(struct udevice *dev)
409961a0b6SThomas Chou {
41bb883f82SStephen Warren struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
42bb883f82SStephen Warren
43bb883f82SStephen Warren if (!uc_priv->clock_rate)
4401476eafSSimon Glass uc_priv->clock_rate = SANDBOX_TIMER_RATE;
45bb883f82SStephen Warren
469961a0b6SThomas Chou return 0;
479961a0b6SThomas Chou }
489961a0b6SThomas Chou
499961a0b6SThomas Chou static const struct timer_ops sandbox_timer_ops = {
509961a0b6SThomas Chou .get_count = sandbox_timer_get_count,
519961a0b6SThomas Chou };
529961a0b6SThomas Chou
539961a0b6SThomas Chou static const struct udevice_id sandbox_timer_ids[] = {
549961a0b6SThomas Chou { .compatible = "sandbox,timer" },
559961a0b6SThomas Chou { }
569961a0b6SThomas Chou };
579961a0b6SThomas Chou
589961a0b6SThomas Chou U_BOOT_DRIVER(sandbox_timer) = {
599961a0b6SThomas Chou .name = "sandbox_timer",
609961a0b6SThomas Chou .id = UCLASS_TIMER,
619961a0b6SThomas Chou .of_match = sandbox_timer_ids,
629961a0b6SThomas Chou .probe = sandbox_timer_probe,
639961a0b6SThomas Chou .ops = &sandbox_timer_ops,
649961a0b6SThomas Chou .flags = DM_FLAG_PRE_RELOC,
659961a0b6SThomas Chou };
66bb883f82SStephen Warren
67bb883f82SStephen Warren /* This is here in case we don't have a device tree */
68bb883f82SStephen Warren U_BOOT_DEVICE(sandbox_timer_non_fdt) = {
69bb883f82SStephen Warren .name = "sandbox_timer",
70bb883f82SStephen Warren };
71