atmel_pit_timer.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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. #include <linux/bitops.h>
  12. #define AT91_PIT_VALUE 0xfffff
  13. #define AT91_PIT_PITEN BIT(24) /* Timer Enabled */
  14. struct atmel_pit_regs {
  15. u32 mode;
  16. u32 status;
  17. u32 value;
  18. u32 value_image;
  19. };
  20. struct atmel_pit_platdata {
  21. struct atmel_pit_regs *regs;
  22. };
  23. static int atmel_pit_get_count(struct udevice *dev, u64 *count)
  24. {
  25. struct atmel_pit_platdata *plat = dev_get_platdata(dev);
  26. struct atmel_pit_regs *const regs = plat->regs;
  27. u32 val = readl(&regs->value_image);
  28. *count = timer_conv_64(val);
  29. return 0;
  30. }
  31. static int atmel_pit_probe(struct udevice *dev)
  32. {
  33. struct atmel_pit_platdata *plat = dev_get_platdata(dev);
  34. struct atmel_pit_regs *const regs = plat->regs;
  35. struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  36. struct clk clk;
  37. ulong clk_rate;
  38. int ret;
  39. ret = clk_get_by_index(dev, 0, &clk);
  40. if (ret)
  41. return -EINVAL;
  42. clk_rate = clk_get_rate(&clk);
  43. if (!clk_rate)
  44. return -EINVAL;
  45. uc_priv->clock_rate = clk_rate / 16;
  46. writel(AT91_PIT_VALUE | AT91_PIT_PITEN, &regs->mode);
  47. return 0;
  48. }
  49. static int atmel_pit_ofdata_to_platdata(struct udevice *dev)
  50. {
  51. struct atmel_pit_platdata *plat = dev_get_platdata(dev);
  52. plat->regs = dev_read_addr_ptr(dev);
  53. return 0;
  54. }
  55. static const struct timer_ops atmel_pit_ops = {
  56. .get_count = atmel_pit_get_count,
  57. };
  58. static const struct udevice_id atmel_pit_ids[] = {
  59. { .compatible = "atmel,at91sam9260-pit" },
  60. { }
  61. };
  62. U_BOOT_DRIVER(atmel_pit) = {
  63. .name = "atmel_pit",
  64. .id = UCLASS_TIMER,
  65. .of_match = atmel_pit_ids,
  66. .ofdata_to_platdata = atmel_pit_ofdata_to_platdata,
  67. .platdata_auto_alloc_size = sizeof(struct atmel_pit_platdata),
  68. .probe = atmel_pit_probe,
  69. .ops = &atmel_pit_ops,
  70. };