clk-rk-gate.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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-gate.h"
  11. rt_inline rt_uint32_t clk_gate_readl(struct rockchip_clk_cell *rk_cell)
  12. {
  13. void *base = rk_cell->provider->reg_base;
  14. if (rk_cell->gate_flags & CLK_GATE_BIG_ENDIAN)
  15. {
  16. return rt_be32_to_cpu(HWREG32(base + rk_cell->gate_offset));
  17. }
  18. return HWREG32(base + rk_cell->gate_offset);
  19. }
  20. rt_inline void clk_gate_writel(struct rockchip_clk_cell *rk_cell, rt_uint32_t val)
  21. {
  22. void *base = rk_cell->provider->reg_base;
  23. if (rk_cell->gate_flags & CLK_GATE_BIG_ENDIAN)
  24. {
  25. HWREG32(base + rk_cell->gate_offset) = rt_cpu_to_be32(val);
  26. }
  27. else
  28. {
  29. HWREG32(base + rk_cell->gate_offset) = val;
  30. }
  31. }
  32. static void clk_gate_endisable(struct rt_clk_cell *cell, int enable)
  33. {
  34. int set;
  35. rt_uint32_t reg;
  36. struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
  37. set = rk_cell->gate_flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
  38. set ^= enable;
  39. if (rk_cell->gate_flags & CLK_GATE_HIWORD_MASK)
  40. {
  41. reg = RT_BIT(rk_cell->gate_shift + 16);
  42. if (set)
  43. {
  44. reg |= RT_BIT(rk_cell->gate_shift);
  45. }
  46. }
  47. else
  48. {
  49. reg = clk_gate_readl(rk_cell);
  50. if (set)
  51. {
  52. reg |= RT_BIT(rk_cell->gate_shift);
  53. }
  54. else
  55. {
  56. reg &= ~RT_BIT(rk_cell->gate_shift);
  57. }
  58. }
  59. clk_gate_writel(rk_cell, reg);
  60. }
  61. static rt_err_t rockchip_gate_clk_enable(struct rt_clk_cell *cell)
  62. {
  63. clk_gate_endisable(cell, 1);
  64. return RT_EOK;
  65. }
  66. static void rockchip_gate_clk_disable(struct rt_clk_cell *cell)
  67. {
  68. clk_gate_endisable(cell, 0);
  69. }
  70. static rt_bool_t rockchip_gate_clk_is_enabled(struct rt_clk_cell *cell)
  71. {
  72. rt_uint32_t reg;
  73. struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
  74. reg = clk_gate_readl(rk_cell);
  75. /* If a set bit disables this clk, flip it before masking */
  76. if (rk_cell->gate_flags & CLK_GATE_SET_TO_DISABLE)
  77. {
  78. reg ^= RT_BIT(rk_cell->gate_shift);
  79. }
  80. reg &= RT_BIT(rk_cell->gate_shift);
  81. return !!reg;
  82. }
  83. const struct rt_clk_ops rockchip_gate_clk_ops =
  84. {
  85. .enable = rockchip_gate_clk_enable,
  86. .disable = rockchip_gate_clk_disable,
  87. .is_enabled = rockchip_gate_clk_is_enabled,
  88. };