atmel_pit_timer.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2017 Microchip Corporation
  4. * Wenyou.Yang <wenyou.yang@microchip.com>
  5. */
  6. #include <common.h>
  7. #include <clk.h>
  8. #include <dm.h>
  9. #include <timer.h>
  10. #include <asm/io.h>
  11. #define AT91_PIT_VALUE 0xfffff
  12. #define AT91_PIT_PITEN BIT(24) /* Timer Enabled */
  13. struct atmel_pit_regs {
  14. u32 mode;
  15. u32 status;
  16. u32 value;
  17. u32 value_image;
  18. };
  19. struct atmel_pit_platdata {
  20. struct atmel_pit_regs *regs;
  21. };
  22. static int atmel_pit_get_count(struct udevice *dev, u64 *count)
  23. {
  24. struct atmel_pit_platdata *plat = dev_get_platdata(dev);
  25. struct atmel_pit_regs *const regs = plat->regs;
  26. u32 val = readl(&regs->value_image);
  27. *count = timer_conv_64(val);
  28. return 0;
  29. }
  30. static int atmel_pit_probe(struct udevice *dev)
  31. {
  32. struct atmel_pit_platdata *plat = dev_get_platdata(dev);
  33. struct atmel_pit_regs *const regs = plat->regs;
  34. struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  35. struct clk clk;
  36. ulong clk_rate;
  37. int ret;
  38. ret = clk_get_by_index(dev, 0, &clk);
  39. if (ret)
  40. return -EINVAL;
  41. clk_rate = clk_get_rate(&clk);
  42. if (!clk_rate)
  43. return -EINVAL;
  44. uc_priv->clock_rate = clk_rate / 16;
  45. writel(AT91_PIT_VALUE | AT91_PIT_PITEN, &regs->mode);
  46. return 0;
  47. }
  48. static int atmel_pit_ofdata_to_platdata(struct udevice *dev)
  49. {
  50. struct atmel_pit_platdata *plat = dev_get_platdata(dev);
  51. plat->regs = (struct atmel_pit_regs *)devfdt_get_addr_ptr(dev);
  52. return 0;
  53. }
  54. static const struct timer_ops atmel_pit_ops = {
  55. .get_count = atmel_pit_get_count,
  56. };
  57. static const struct udevice_id atmel_pit_ids[] = {
  58. { .compatible = "atmel,at91sam9260-pit" },
  59. { }
  60. };
  61. U_BOOT_DRIVER(atmel_pit) = {
  62. .name = "atmel_pit",
  63. .id = UCLASS_TIMER,
  64. .of_match = atmel_pit_ids,
  65. .ofdata_to_platdata = atmel_pit_ofdata_to_platdata,
  66. .platdata_auto_alloc_size = sizeof(struct atmel_pit_platdata),
  67. .probe = atmel_pit_probe,
  68. .ops = &atmel_pit_ops,
  69. };