riscv_timer.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2020, Sean Anderson <seanga2@gmail.com>
  4. * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
  5. * Copyright (C) 2018, Anup Patel <anup@brainfault.org>
  6. * Copyright (C) 2012 Regents of the University of California
  7. *
  8. * RISC-V architecturally-defined generic timer driver
  9. *
  10. * This driver provides generic timer support for S-mode U-Boot.
  11. */
  12. #include <common.h>
  13. #include <dm.h>
  14. #include <errno.h>
  15. #include <timer.h>
  16. #include <asm/csr.h>
  17. static int riscv_timer_get_count(struct udevice *dev, u64 *count)
  18. {
  19. if (IS_ENABLED(CONFIG_64BIT)) {
  20. *count = csr_read(CSR_TIME);
  21. } else {
  22. u32 hi, lo;
  23. do {
  24. hi = csr_read(CSR_TIMEH);
  25. lo = csr_read(CSR_TIME);
  26. } while (hi != csr_read(CSR_TIMEH));
  27. *count = ((u64)hi << 32) | lo;
  28. }
  29. return 0;
  30. }
  31. static int riscv_timer_probe(struct udevice *dev)
  32. {
  33. struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  34. /* clock frequency was passed from the cpu driver as driver data */
  35. uc_priv->clock_rate = dev->driver_data;
  36. return 0;
  37. }
  38. static const struct timer_ops riscv_timer_ops = {
  39. .get_count = riscv_timer_get_count,
  40. };
  41. U_BOOT_DRIVER(riscv_timer) = {
  42. .name = "riscv_timer",
  43. .id = UCLASS_TIMER,
  44. .probe = riscv_timer_probe,
  45. .ops = &riscv_timer_ops,
  46. .flags = DM_FLAG_PRE_RELOC,
  47. };