mtk_timer.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * MediaTek timer driver
  4. *
  5. * Copyright (C) 2018 MediaTek Inc.
  6. * Author: Ryder Lee <ryder.lee@mediatek.com>
  7. */
  8. #include <clk.h>
  9. #include <common.h>
  10. #include <dm.h>
  11. #include <timer.h>
  12. #include <asm/io.h>
  13. #include <linux/bitops.h>
  14. #define MTK_GPT4_CTRL 0x40
  15. #define MTK_GPT4_CLK 0x44
  16. #define MTK_GPT4_CNT 0x48
  17. #define GPT4_ENABLE BIT(0)
  18. #define GPT4_CLEAR BIT(1)
  19. #define GPT4_FREERUN GENMASK(5, 4)
  20. #define GPT4_CLK_SYS 0x0
  21. #define GPT4_CLK_DIV1 0x0
  22. struct mtk_timer_priv {
  23. void __iomem *base;
  24. };
  25. static int mtk_timer_get_count(struct udevice *dev, u64 *count)
  26. {
  27. struct mtk_timer_priv *priv = dev_get_priv(dev);
  28. u32 val = readl(priv->base + MTK_GPT4_CNT);
  29. *count = timer_conv_64(val);
  30. return 0;
  31. }
  32. static int mtk_timer_probe(struct udevice *dev)
  33. {
  34. struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  35. struct mtk_timer_priv *priv = dev_get_priv(dev);
  36. struct clk clk, parent;
  37. int ret;
  38. priv->base = dev_read_addr_ptr(dev);
  39. if (!priv->base)
  40. return -ENOENT;
  41. ret = clk_get_by_index(dev, 0, &clk);
  42. if (ret)
  43. return ret;
  44. ret = clk_get_by_index(dev, 1, &parent);
  45. if (!ret) {
  46. ret = clk_set_parent(&clk, &parent);
  47. if (ret)
  48. return ret;
  49. }
  50. uc_priv->clock_rate = clk_get_rate(&clk);
  51. if (!uc_priv->clock_rate)
  52. return -EINVAL;
  53. return 0;
  54. }
  55. static const struct timer_ops mtk_timer_ops = {
  56. .get_count = mtk_timer_get_count,
  57. };
  58. static const struct udevice_id mtk_timer_ids[] = {
  59. { .compatible = "mediatek,timer" },
  60. { .compatible = "mediatek,mt6577-timer" },
  61. { }
  62. };
  63. U_BOOT_DRIVER(mtk_timer) = {
  64. .name = "mtk_timer",
  65. .id = UCLASS_TIMER,
  66. .of_match = mtk_timer_ids,
  67. .priv_auto_alloc_size = sizeof(struct mtk_timer_priv),
  68. .probe = mtk_timer_probe,
  69. .ops = &mtk_timer_ops,
  70. .flags = DM_FLAG_PRE_RELOC,
  71. };