riscv_aclint_timer.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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. */
  6. #include <common.h>
  7. #include <clk.h>
  8. #include <dm.h>
  9. #include <timer.h>
  10. #include <asm/io.h>
  11. #include <dm/device-internal.h>
  12. #include <linux/err.h>
  13. #define CLINT_MTIME_OFFSET 0xbff8
  14. #define ACLINT_MTIME_OFFSET 0
  15. /* mtime register */
  16. #define MTIME_REG(base, offset) ((ulong)(base) + (offset))
  17. static u64 notrace riscv_aclint_timer_get_count(struct udevice *dev)
  18. {
  19. return readq((void __iomem *)MTIME_REG(dev_get_priv(dev),
  20. dev_get_driver_data(dev)));
  21. }
  22. #if CONFIG_IS_ENABLED(RISCV_MMODE) && IS_ENABLED(CONFIG_TIMER_EARLY)
  23. /**
  24. * timer_early_get_rate() - Get the timer rate before driver model
  25. */
  26. unsigned long notrace timer_early_get_rate(void)
  27. {
  28. return RISCV_MMODE_TIMER_FREQ;
  29. }
  30. /**
  31. * timer_early_get_count() - Get the timer count before driver model
  32. *
  33. */
  34. u64 notrace timer_early_get_count(void)
  35. {
  36. return readq((void __iomem *)MTIME_REG(RISCV_MMODE_TIMERBASE,
  37. RISCV_MMODE_TIMEROFF));
  38. }
  39. #endif
  40. static const struct timer_ops riscv_aclint_timer_ops = {
  41. .get_count = riscv_aclint_timer_get_count,
  42. };
  43. static int riscv_aclint_timer_probe(struct udevice *dev)
  44. {
  45. dev_set_priv(dev, dev_read_addr_ptr(dev));
  46. if (!dev_get_priv(dev))
  47. return -EINVAL;
  48. return timer_timebase_fallback(dev);
  49. }
  50. static const struct udevice_id riscv_aclint_timer_ids[] = {
  51. { .compatible = "riscv,clint0", .data = CLINT_MTIME_OFFSET },
  52. { .compatible = "sifive,clint0", .data = CLINT_MTIME_OFFSET },
  53. { .compatible = "riscv,aclint-mtimer", .data = ACLINT_MTIME_OFFSET },
  54. { }
  55. };
  56. U_BOOT_DRIVER(riscv_aclint_timer) = {
  57. .name = "riscv_aclint_timer",
  58. .id = UCLASS_TIMER,
  59. .of_match = riscv_aclint_timer_ids,
  60. .probe = riscv_aclint_timer_probe,
  61. .ops = &riscv_aclint_timer_ops,
  62. .flags = DM_FLAG_PRE_RELOC,
  63. };