mtk_timer.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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 u64 mtk_timer_get_count(struct udevice *dev)
  26. {
  27. struct mtk_timer_priv *priv = dev_get_priv(dev);
  28. u32 val = readl(priv->base + MTK_GPT4_CNT);
  29. return timer_conv_64(val);
  30. }
  31. static int mtk_timer_probe(struct udevice *dev)
  32. {
  33. struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  34. struct mtk_timer_priv *priv = dev_get_priv(dev);
  35. struct clk clk, parent;
  36. int ret;
  37. priv->base = dev_read_addr_ptr(dev);
  38. if (!priv->base)
  39. return -ENOENT;
  40. ret = clk_get_by_index(dev, 0, &clk);
  41. if (ret)
  42. return ret;
  43. ret = clk_get_by_index(dev, 1, &parent);
  44. if (!ret) {
  45. ret = clk_set_parent(&clk, &parent);
  46. if (ret)
  47. return ret;
  48. }
  49. uc_priv->clock_rate = clk_get_rate(&clk);
  50. if (!uc_priv->clock_rate)
  51. return -EINVAL;
  52. return 0;
  53. }
  54. static const struct timer_ops mtk_timer_ops = {
  55. .get_count = mtk_timer_get_count,
  56. };
  57. static const struct udevice_id mtk_timer_ids[] = {
  58. { .compatible = "mediatek,timer" },
  59. { .compatible = "mediatek,mt6577-timer" },
  60. { }
  61. };
  62. U_BOOT_DRIVER(mtk_timer) = {
  63. .name = "mtk_timer",
  64. .id = UCLASS_TIMER,
  65. .of_match = mtk_timer_ids,
  66. .priv_auto_alloc_size = sizeof(struct mtk_timer_priv),
  67. .probe = mtk_timer_probe,
  68. .ops = &mtk_timer_ops,
  69. .flags = DM_FLAG_PRE_RELOC,
  70. };