ccu_mp.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright (c) 2016 Maxime Ripard. All rights reserved.
  3. *
  4. * This software is licensed under the terms of the GNU General Public
  5. * License version 2, as published by the Free Software Foundation, and
  6. * may be copied, distributed, and modified under those terms.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #ifndef _CCU_MP_H_
  14. #define _CCU_MP_H_
  15. #include <linux/bitops.h>
  16. #include <linux/clk-provider.h>
  17. #include "ccu_common.h"
  18. #include "ccu_div.h"
  19. #include "ccu_mult.h"
  20. #include "ccu_mux.h"
  21. /*
  22. * struct ccu_mp - Definition of an M-P clock
  23. *
  24. * Clocks based on the formula parent >> P / M
  25. */
  26. struct ccu_mp {
  27. u32 enable;
  28. struct ccu_div_internal m;
  29. struct ccu_div_internal p;
  30. struct ccu_mux_internal mux;
  31. unsigned int fixed_post_div;
  32. struct ccu_common common;
  33. };
  34. #define SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(_struct, _name, _parents, _reg, \
  35. _mshift, _mwidth, \
  36. _pshift, _pwidth, \
  37. _muxshift, _muxwidth, \
  38. _gate, _postdiv, _flags) \
  39. struct ccu_mp _struct = { \
  40. .enable = _gate, \
  41. .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
  42. .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \
  43. .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
  44. .fixed_post_div = _postdiv, \
  45. .common = { \
  46. .reg = _reg, \
  47. .features = CCU_FEATURE_FIXED_POSTDIV, \
  48. .hw.init = CLK_HW_INIT_PARENTS(_name, \
  49. _parents, \
  50. &ccu_mp_ops, \
  51. _flags), \
  52. } \
  53. }
  54. #define SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
  55. _mshift, _mwidth, \
  56. _pshift, _pwidth, \
  57. _muxshift, _muxwidth, \
  58. _gate, _flags) \
  59. struct ccu_mp _struct = { \
  60. .enable = _gate, \
  61. .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
  62. .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \
  63. .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
  64. .common = { \
  65. .reg = _reg, \
  66. .hw.init = CLK_HW_INIT_PARENTS(_name, \
  67. _parents, \
  68. &ccu_mp_ops, \
  69. _flags), \
  70. } \
  71. }
  72. #define SUNXI_CCU_MP_WITH_MUX(_struct, _name, _parents, _reg, \
  73. _mshift, _mwidth, \
  74. _pshift, _pwidth, \
  75. _muxshift, _muxwidth, \
  76. _flags) \
  77. SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
  78. _mshift, _mwidth, \
  79. _pshift, _pwidth, \
  80. _muxshift, _muxwidth, \
  81. 0, _flags)
  82. static inline struct ccu_mp *hw_to_ccu_mp(struct clk_hw *hw)
  83. {
  84. struct ccu_common *common = hw_to_ccu_common(hw);
  85. return container_of(common, struct ccu_mp, common);
  86. }
  87. extern const struct clk_ops ccu_mp_ops;
  88. /*
  89. * Special class of M-P clock that supports MMC timing modes
  90. *
  91. * Since the MMC clock registers all follow the same layout, we can
  92. * simplify the macro for this particular case. In addition, as
  93. * switching modes also affects the output clock rate, we need to
  94. * have CLK_GET_RATE_NOCACHE for all these types of clocks.
  95. */
  96. #define SUNXI_CCU_MP_MMC_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
  97. _flags) \
  98. struct ccu_mp _struct = { \
  99. .enable = BIT(31), \
  100. .m = _SUNXI_CCU_DIV(0, 4), \
  101. .p = _SUNXI_CCU_DIV(16, 2), \
  102. .mux = _SUNXI_CCU_MUX(24, 2), \
  103. .common = { \
  104. .reg = _reg, \
  105. .features = CCU_FEATURE_MMC_TIMING_SWITCH, \
  106. .hw.init = CLK_HW_INIT_PARENTS(_name, \
  107. _parents, \
  108. &ccu_mp_mmc_ops, \
  109. CLK_GET_RATE_NOCACHE | \
  110. _flags), \
  111. } \
  112. }
  113. extern const struct clk_ops ccu_mp_mmc_ops;
  114. #endif /* _CCU_MP_H_ */