timer-uclass.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <dm.h>
  8. #include <dm/lists.h>
  9. #include <dm/device-internal.h>
  10. #include <dm/root.h>
  11. #include <clk.h>
  12. #include <errno.h>
  13. #include <timer.h>
  14. DECLARE_GLOBAL_DATA_PTR;
  15. /*
  16. * Implement a timer uclass to work with lib/time.c. The timer is usually
  17. * a 32/64 bits free-running up counter. The get_rate() method is used to get
  18. * the input clock frequency of the timer. The get_count() method is used
  19. * to get the current 64 bits count value. If the hardware is counting down,
  20. * the value should be inversed inside the method. There may be no real
  21. * tick, and no timer interrupt.
  22. */
  23. int notrace timer_get_count(struct udevice *dev, u64 *count)
  24. {
  25. const struct timer_ops *ops = device_get_ops(dev);
  26. if (!ops->get_count)
  27. return -ENOSYS;
  28. return ops->get_count(dev, count);
  29. }
  30. unsigned long notrace timer_get_rate(struct udevice *dev)
  31. {
  32. struct timer_dev_priv *uc_priv = dev->uclass_priv;
  33. return uc_priv->clock_rate;
  34. }
  35. static int timer_pre_probe(struct udevice *dev)
  36. {
  37. #if !CONFIG_IS_ENABLED(OF_PLATDATA)
  38. struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  39. struct clk timer_clk;
  40. int err;
  41. ulong ret;
  42. err = clk_get_by_index(dev, 0, &timer_clk);
  43. if (!err) {
  44. ret = clk_get_rate(&timer_clk);
  45. if (IS_ERR_VALUE(ret))
  46. return ret;
  47. uc_priv->clock_rate = ret;
  48. } else {
  49. uc_priv->clock_rate =
  50. dev_read_u32_default(dev, "clock-frequency", 0);
  51. }
  52. #endif
  53. return 0;
  54. }
  55. static int timer_post_probe(struct udevice *dev)
  56. {
  57. struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  58. if (!uc_priv->clock_rate)
  59. return -EINVAL;
  60. return 0;
  61. }
  62. u64 timer_conv_64(u32 count)
  63. {
  64. /* increment tbh if tbl has rolled over */
  65. if (count < gd->timebase_l)
  66. gd->timebase_h++;
  67. gd->timebase_l = count;
  68. return ((u64)gd->timebase_h << 32) | gd->timebase_l;
  69. }
  70. int notrace dm_timer_init(void)
  71. {
  72. struct udevice *dev = NULL;
  73. __maybe_unused ofnode node;
  74. int ret;
  75. if (gd->timer)
  76. return 0;
  77. /*
  78. * Directly access gd->dm_root to suppress error messages, if the
  79. * virtual root driver does not yet exist.
  80. */
  81. if (gd->dm_root == NULL)
  82. return -EAGAIN;
  83. #if !CONFIG_IS_ENABLED(OF_PLATDATA)
  84. /* Check for a chosen timer to be used for tick */
  85. node = ofnode_get_chosen_node("tick-timer");
  86. if (ofnode_valid(node) &&
  87. uclass_get_device_by_ofnode(UCLASS_TIMER, node, &dev)) {
  88. /*
  89. * If the timer is not marked to be bound before
  90. * relocation, bind it anyway.
  91. */
  92. if (!lists_bind_fdt(dm_root(), node, &dev)) {
  93. ret = device_probe(dev);
  94. if (ret)
  95. return ret;
  96. }
  97. }
  98. #endif
  99. if (!dev) {
  100. /* Fall back to the first available timer */
  101. ret = uclass_first_device_err(UCLASS_TIMER, &dev);
  102. if (ret)
  103. return ret;
  104. }
  105. if (dev) {
  106. gd->timer = dev;
  107. return 0;
  108. }
  109. return -ENODEV;
  110. }
  111. UCLASS_DRIVER(timer) = {
  112. .id = UCLASS_TIMER,
  113. .name = "timer",
  114. .pre_probe = timer_pre_probe,
  115. .flags = DM_UC_FLAG_SEQ_ALIAS,
  116. .post_probe = timer_post_probe,
  117. .per_device_auto_alloc_size = sizeof(struct timer_dev_priv),
  118. };