pmc.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2016 Atmel Corporation
  4. * Wenyou.Yang <wenyou.yang@atmel.com>
  5. */
  6. #include <asm/io.h>
  7. #include <clk-uclass.h>
  8. #include <common.h>
  9. #include "pmc.h"
  10. static int at91_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
  11. {
  12. if (args->args_count != 2) {
  13. debug("AT91: clk: Invalid args_count: %d\n", args->args_count);
  14. return -EINVAL;
  15. }
  16. clk->id = AT91_TO_CLK_ID(args->args[0], args->args[1]);
  17. return 0;
  18. }
  19. static ulong at91_clk_get_rate(struct clk *clk)
  20. {
  21. struct clk *c;
  22. int ret;
  23. ret = clk_get_by_id(clk->id, &c);
  24. if (ret)
  25. return ret;
  26. return clk_get_rate(c);
  27. }
  28. static ulong at91_clk_set_rate(struct clk *clk, ulong rate)
  29. {
  30. struct clk *c;
  31. int ret;
  32. ret = clk_get_by_id(clk->id, &c);
  33. if (ret)
  34. return ret;
  35. return clk_set_rate(c, rate);
  36. }
  37. static int at91_clk_enable(struct clk *clk)
  38. {
  39. struct clk *c;
  40. int ret;
  41. ret = clk_get_by_id(clk->id, &c);
  42. if (ret)
  43. return ret;
  44. return clk_enable(c);
  45. }
  46. static int at91_clk_disable(struct clk *clk)
  47. {
  48. struct clk *c;
  49. int ret;
  50. ret = clk_get_by_id(clk->id, &c);
  51. if (ret)
  52. return ret;
  53. return clk_disable(c);
  54. }
  55. const struct clk_ops at91_clk_ops = {
  56. .of_xlate = at91_clk_of_xlate,
  57. .set_rate = at91_clk_set_rate,
  58. .get_rate = at91_clk_get_rate,
  59. .enable = at91_clk_enable,
  60. .disable = at91_clk_disable,
  61. };
  62. /**
  63. * pmc_read() - read content at address base + off into val
  64. *
  65. * @base: base address
  66. * @off: offset to read from
  67. * @val: where the content of base + off is stored
  68. *
  69. * @return: void
  70. */
  71. void pmc_read(void __iomem *base, unsigned int off, unsigned int *val)
  72. {
  73. *val = readl(base + off);
  74. }
  75. /**
  76. * pmc_write() - write content of val at address base + off
  77. *
  78. * @base: base address
  79. * @off: offset to write to
  80. * @val: content to be written at base + off
  81. *
  82. * @return: void
  83. */
  84. void pmc_write(void __iomem *base, unsigned int off, unsigned int val)
  85. {
  86. writel(val, base + off);
  87. }
  88. /**
  89. * pmc_update_bits() - update a set of bits at address base + off
  90. *
  91. * @base: base address
  92. * @off: offset to be updated
  93. * @mask: mask of bits to be updated
  94. * @bits: the new value to be updated
  95. *
  96. * @return: void
  97. */
  98. void pmc_update_bits(void __iomem *base, unsigned int off,
  99. unsigned int mask, unsigned int bits)
  100. {
  101. unsigned int tmp;
  102. tmp = readl(base + off);
  103. tmp &= ~mask;
  104. writel(tmp | (bits & mask), base + off);
  105. }
  106. /**
  107. * at91_clk_mux_val_to_index() - get parent index in mux table
  108. *
  109. * @table: clock mux table
  110. * @num_parents: clock number of parents
  111. * @val: clock id who's mux index should be retrieved
  112. *
  113. * @return: clock index in mux table or a negative error number in case of
  114. * failure
  115. */
  116. int at91_clk_mux_val_to_index(const u32 *table, u32 num_parents, u32 val)
  117. {
  118. int i;
  119. if (!table || !num_parents)
  120. return -EINVAL;
  121. for (i = 0; i < num_parents; i++) {
  122. if (table[i] == val)
  123. return i;
  124. }
  125. return -EINVAL;
  126. }
  127. /**
  128. * at91_clk_mux_index_to_val() - get parent ID corresponding to an entry in
  129. * clock's mux table
  130. *
  131. * @table: clock's mux table
  132. * @num_parents: clock's number of parents
  133. * @index: index in mux table which clock's ID should be retrieved
  134. *
  135. * @return: clock ID or a negative error number in case of failure
  136. */
  137. int at91_clk_mux_index_to_val(const u32 *table, u32 num_parents, u32 index)
  138. {
  139. if (!table || !num_parents || index < 0 || index > num_parents)
  140. return -EINVAL;
  141. return table[index];
  142. }