clk-rk-mux.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-3-08 GuEe-GUI the first version
  9. */
  10. #include "clk-rk-mux.h"
  11. rt_inline rt_uint32_t clk_mux_readl(struct rockchip_clk_cell *rk_cell)
  12. {
  13. void *base = rk_cell->provider->reg_base;
  14. if (rk_cell->mux_flags & CLK_MUX_BIG_ENDIAN)
  15. {
  16. return rt_be32_to_cpu(HWREG32(base + rk_cell->muxdiv_offset));
  17. }
  18. return HWREG32(base + rk_cell->muxdiv_offset);
  19. }
  20. rt_inline void clk_mux_writel(struct rockchip_clk_cell *rk_cell, rt_uint32_t val)
  21. {
  22. void *base = rk_cell->provider->reg_base;
  23. if (rk_cell->mux_flags & CLK_MUX_BIG_ENDIAN)
  24. {
  25. HWREG32(base + rk_cell->muxdiv_offset) = rt_cpu_to_be32(val);
  26. }
  27. else
  28. {
  29. HWREG32(base + rk_cell->muxdiv_offset) = val;
  30. }
  31. }
  32. static int clk_mux_val_to_index(struct rt_clk_cell *cell,
  33. const rt_uint32_t *table, rt_uint32_t flags, rt_uint32_t val)
  34. {
  35. int num_parents = cell->parents_nr;
  36. if (table)
  37. {
  38. for (int i = 0; i < num_parents; ++i)
  39. {
  40. if (table[i] == val)
  41. {
  42. return i;
  43. }
  44. }
  45. return -RT_EINVAL;
  46. }
  47. if (val && (flags & CLK_MUX_INDEX_BIT))
  48. {
  49. val = __rt_ffs(val) - 1;
  50. }
  51. if (val && (flags & CLK_MUX_INDEX_ONE))
  52. {
  53. --val;
  54. }
  55. if (val >= num_parents)
  56. {
  57. return -RT_EINVAL;
  58. }
  59. return val;
  60. }
  61. static rt_uint32_t clk_mux_index_to_val(const rt_uint32_t *table, rt_uint32_t flags, rt_uint8_t index)
  62. {
  63. rt_uint32_t val = index;
  64. if (table)
  65. {
  66. val = table[index];
  67. }
  68. else
  69. {
  70. if (flags & CLK_MUX_INDEX_BIT)
  71. {
  72. val = 1 << index;
  73. }
  74. if (flags & CLK_MUX_INDEX_ONE)
  75. {
  76. val++;
  77. }
  78. }
  79. return val;
  80. }
  81. static rt_err_t rockchip_mux_clk_set_parent(struct rt_clk_cell *cell, rt_uint8_t index)
  82. {
  83. rt_uint32_t val, reg;
  84. struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
  85. val = clk_mux_index_to_val(rk_cell->mux_table, rk_cell->mux_flags, index);
  86. if (rk_cell->mux_flags & CLK_MUX_HIWORD_MASK)
  87. {
  88. reg = rk_cell->mux_mask << (rk_cell->mux_shift + 16);
  89. }
  90. else
  91. {
  92. reg = clk_mux_readl(rk_cell);
  93. reg &= ~(rk_cell->mux_mask << rk_cell->mux_shift);
  94. }
  95. val = val << rk_cell->mux_shift;
  96. reg |= val;
  97. clk_mux_writel(rk_cell, reg);
  98. return RT_EOK;
  99. }
  100. static rt_uint8_t rockchip_mux_clk_get_parent(struct rt_clk_cell *cell)
  101. {
  102. rt_uint32_t val;
  103. struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
  104. val = clk_mux_readl(rk_cell) >> rk_cell->mux_shift;
  105. val &= rk_cell->mux_mask;
  106. return clk_mux_val_to_index(cell, rk_cell->mux_table, rk_cell->mux_flags, val);
  107. }
  108. const struct rt_clk_ops rockchip_mux_clk_ops =
  109. {
  110. .set_parent = rockchip_mux_clk_set_parent,
  111. .get_parent = rockchip_mux_clk_get_parent,
  112. };
  113. const struct rt_clk_ops rockchip_mux_ro_clk_ops =
  114. {
  115. .get_parent = rockchip_mux_clk_get_parent,
  116. };
  117. void rockchip_mux_clk_cell_init(struct rockchip_clk_cell *rk_cell)
  118. {
  119. rk_cell->mux_mask = RT_BIT(rk_cell->mux_width) - 1;
  120. if (!rk_cell->cell.ops)
  121. {
  122. if (!((rk_cell->mux_flags & CLK_MUX_READ_ONLY)))
  123. {
  124. rk_cell->cell.ops = &rockchip_mux_clk_ops;
  125. }
  126. else
  127. {
  128. rk_cell->cell.ops = &rockchip_mux_ro_clk_ops;
  129. }
  130. }
  131. }