xref: /rk3399_rockchip-uboot/drivers/timer/sandbox_timer.c (revision d5c6144fe326e255e42ec273fc5d88f45cd61548)
19961a0b6SThomas Chou /*
29961a0b6SThomas Chou  * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
39961a0b6SThomas Chou  *
49961a0b6SThomas Chou  * SPDX-License-Identifier:	GPL-2.0+
59961a0b6SThomas Chou  */
69961a0b6SThomas Chou 
79961a0b6SThomas Chou #include <common.h>
89961a0b6SThomas Chou #include <dm.h>
99961a0b6SThomas Chou #include <errno.h>
109961a0b6SThomas Chou #include <timer.h>
119961a0b6SThomas Chou #include <os.h>
129961a0b6SThomas Chou 
13*01476eafSSimon Glass #define SANDBOX_TIMER_RATE	1000000
14*01476eafSSimon Glass 
159961a0b6SThomas Chou /* system timer offset in ms */
169961a0b6SThomas Chou static unsigned long sandbox_timer_offset;
179961a0b6SThomas Chou 
sandbox_timer_add_offset(unsigned long offset)189961a0b6SThomas Chou void sandbox_timer_add_offset(unsigned long offset)
199961a0b6SThomas Chou {
209961a0b6SThomas Chou 	sandbox_timer_offset += offset;
219961a0b6SThomas Chou }
229961a0b6SThomas Chou 
timer_early_get_count(void)23*01476eafSSimon Glass u64 notrace timer_early_get_count(void)
249961a0b6SThomas Chou {
25*01476eafSSimon Glass 	return os_get_nsec() / 1000 + sandbox_timer_offset * 1000;
26*01476eafSSimon Glass }
27*01476eafSSimon Glass 
timer_early_get_rate(void)28*01476eafSSimon Glass unsigned long notrace timer_early_get_rate(void)
29*01476eafSSimon Glass {
30*01476eafSSimon Glass 	return SANDBOX_TIMER_RATE;
31*01476eafSSimon Glass }
32*01476eafSSimon Glass 
sandbox_timer_get_count(struct udevice * dev,u64 * count)33*01476eafSSimon Glass static notrace int sandbox_timer_get_count(struct udevice *dev, u64 *count)
34*01476eafSSimon Glass {
35*01476eafSSimon Glass 	*count = timer_early_get_count();
369961a0b6SThomas Chou 
379961a0b6SThomas Chou 	return 0;
389961a0b6SThomas Chou }
399961a0b6SThomas Chou 
sandbox_timer_probe(struct udevice * dev)409961a0b6SThomas Chou static int sandbox_timer_probe(struct udevice *dev)
419961a0b6SThomas Chou {
42bb883f82SStephen Warren 	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
43bb883f82SStephen Warren 
44bb883f82SStephen Warren 	if (!uc_priv->clock_rate)
45*01476eafSSimon Glass 		uc_priv->clock_rate = SANDBOX_TIMER_RATE;
46bb883f82SStephen Warren 
479961a0b6SThomas Chou 	return 0;
489961a0b6SThomas Chou }
499961a0b6SThomas Chou 
509961a0b6SThomas Chou static const struct timer_ops sandbox_timer_ops = {
519961a0b6SThomas Chou 	.get_count = sandbox_timer_get_count,
529961a0b6SThomas Chou };
539961a0b6SThomas Chou 
549961a0b6SThomas Chou static const struct udevice_id sandbox_timer_ids[] = {
559961a0b6SThomas Chou 	{ .compatible = "sandbox,timer" },
569961a0b6SThomas Chou 	{ }
579961a0b6SThomas Chou };
589961a0b6SThomas Chou 
599961a0b6SThomas Chou U_BOOT_DRIVER(sandbox_timer) = {
609961a0b6SThomas Chou 	.name	= "sandbox_timer",
619961a0b6SThomas Chou 	.id	= UCLASS_TIMER,
629961a0b6SThomas Chou 	.of_match = sandbox_timer_ids,
639961a0b6SThomas Chou 	.probe = sandbox_timer_probe,
649961a0b6SThomas Chou 	.ops	= &sandbox_timer_ops,
659961a0b6SThomas Chou 	.flags = DM_FLAG_PRE_RELOC,
669961a0b6SThomas Chou };
67bb883f82SStephen Warren 
68bb883f82SStephen Warren /* This is here in case we don't have a device tree */
69bb883f82SStephen Warren U_BOOT_DEVICE(sandbox_timer_non_fdt) = {
70bb883f82SStephen Warren 	.name = "sandbox_timer",
71bb883f82SStephen Warren };
72