clk-mux.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (c) 2018 MediaTek Inc.
  4. * Author: Owen Chen <owen.chen@mediatek.com>
  5. */
  6. #ifndef __DRV_CLK_MTK_MUX_H
  7. #define __DRV_CLK_MTK_MUX_H
  8. #include <linux/notifier.h>
  9. #include <linux/spinlock.h>
  10. #include <linux/types.h>
  11. struct clk;
  12. struct clk_hw_onecell_data;
  13. struct clk_ops;
  14. struct device;
  15. struct device_node;
  16. struct mtk_mux {
  17. int id;
  18. const char *name;
  19. const char * const *parent_names;
  20. const u8 *parent_index;
  21. unsigned int flags;
  22. u32 mux_ofs;
  23. u32 set_ofs;
  24. u32 clr_ofs;
  25. u32 upd_ofs;
  26. u32 hwv_set_ofs;
  27. u32 hwv_clr_ofs;
  28. u32 hwv_sta_ofs;
  29. u32 fenc_sta_mon_ofs;
  30. u8 mux_shift;
  31. u8 mux_width;
  32. u8 gate_shift;
  33. s8 upd_shift;
  34. u8 fenc_shift;
  35. const struct clk_ops *ops;
  36. signed char num_parents;
  37. };
  38. #define __GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _paridx, \
  39. _num_parents, _mux_ofs, _mux_set_ofs, \
  40. _mux_clr_ofs, _shift, _width, _gate, _upd_ofs, \
  41. _upd, _flags, _ops) { \
  42. .id = _id, \
  43. .name = _name, \
  44. .mux_ofs = _mux_ofs, \
  45. .set_ofs = _mux_set_ofs, \
  46. .clr_ofs = _mux_clr_ofs, \
  47. .upd_ofs = _upd_ofs, \
  48. .mux_shift = _shift, \
  49. .mux_width = _width, \
  50. .gate_shift = _gate, \
  51. .upd_shift = _upd, \
  52. .parent_names = _parents, \
  53. .parent_index = _paridx, \
  54. .num_parents = _num_parents, \
  55. .flags = _flags, \
  56. .ops = &_ops, \
  57. }
  58. #define GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \
  59. _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
  60. _gate, _upd_ofs, _upd, _flags, _ops) \
  61. __GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, \
  62. NULL, ARRAY_SIZE(_parents), _mux_ofs, \
  63. _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
  64. _gate, _upd_ofs, _upd, _flags, _ops) \
  65. #define GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, _parents, _paridx, \
  66. _mux_ofs, _mux_set_ofs, _mux_clr_ofs, _shift, \
  67. _width, _gate, _upd_ofs, _upd, _flags, _ops) \
  68. __GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, \
  69. _paridx, ARRAY_SIZE(_paridx), _mux_ofs, \
  70. _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
  71. _gate, _upd_ofs, _upd, _flags, _ops) \
  72. extern const struct clk_ops mtk_mux_clr_set_upd_ops;
  73. extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops;
  74. extern const struct clk_ops mtk_mux_gate_fenc_clr_set_upd_ops;
  75. extern const struct clk_ops mtk_mux_gate_hwv_fenc_clr_set_upd_ops;
  76. #define MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \
  77. _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
  78. _gate, _upd_ofs, _upd, _flags) \
  79. GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \
  80. _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
  81. _gate, _upd_ofs, _upd, _flags, \
  82. mtk_mux_gate_clr_set_upd_ops)
  83. #define MUX_GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, _parents, \
  84. _paridx, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \
  85. _shift, _width, _gate, _upd_ofs, _upd, _flags) \
  86. GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, _parents, \
  87. _paridx, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \
  88. _shift, _width, _gate, _upd_ofs, _upd, _flags, \
  89. mtk_mux_gate_clr_set_upd_ops)
  90. #define MUX_GATE_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, \
  91. _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
  92. _gate, _upd_ofs, _upd) \
  93. MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, \
  94. _mux_ofs, _mux_set_ofs, _mux_clr_ofs, _shift, \
  95. _width, _gate, _upd_ofs, _upd, \
  96. CLK_SET_RATE_PARENT)
  97. #define MUX_GATE_CLR_SET_UPD_INDEXED(_id, _name, _parents, _paridx, \
  98. _mux_ofs, _mux_set_ofs, _mux_clr_ofs, _shift, \
  99. _width, _gate, _upd_ofs, _upd) \
  100. MUX_GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, \
  101. _parents, _paridx, _mux_ofs, _mux_set_ofs, \
  102. _mux_clr_ofs, _shift, _width, _gate, _upd_ofs, \
  103. _upd, CLK_SET_RATE_PARENT)
  104. #define MUX_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, \
  105. _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
  106. _upd_ofs, _upd) \
  107. GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \
  108. _mux_set_ofs, _mux_clr_ofs, _shift, _width, \
  109. 0, _upd_ofs, _upd, CLK_SET_RATE_PARENT, \
  110. mtk_mux_clr_set_upd_ops)
  111. #define MUX_GATE_HWV_FENC_CLR_SET_UPD_FLAGS(_id, _name, _parents, \
  112. _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \
  113. _hwv_sta_ofs, _hwv_set_ofs, _hwv_clr_ofs, \
  114. _shift, _width, _gate, _upd_ofs, _upd, \
  115. _fenc_sta_mon_ofs, _fenc, _flags) { \
  116. .id = _id, \
  117. .name = _name, \
  118. .mux_ofs = _mux_ofs, \
  119. .set_ofs = _mux_set_ofs, \
  120. .clr_ofs = _mux_clr_ofs, \
  121. .hwv_sta_ofs = _hwv_sta_ofs, \
  122. .hwv_set_ofs = _hwv_set_ofs, \
  123. .hwv_clr_ofs = _hwv_clr_ofs, \
  124. .upd_ofs = _upd_ofs, \
  125. .fenc_sta_mon_ofs = _fenc_sta_mon_ofs, \
  126. .mux_shift = _shift, \
  127. .mux_width = _width, \
  128. .gate_shift = _gate, \
  129. .upd_shift = _upd, \
  130. .fenc_shift = _fenc, \
  131. .parent_names = _parents, \
  132. .num_parents = ARRAY_SIZE(_parents), \
  133. .flags = _flags, \
  134. .ops = &mtk_mux_gate_hwv_fenc_clr_set_upd_ops, \
  135. }
  136. #define MUX_GATE_HWV_FENC_CLR_SET_UPD(_id, _name, _parents, \
  137. _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \
  138. _hwv_sta_ofs, _hwv_set_ofs, _hwv_clr_ofs, \
  139. _shift, _width, _gate, _upd_ofs, _upd, \
  140. _fenc_sta_mon_ofs, _fenc) \
  141. MUX_GATE_HWV_FENC_CLR_SET_UPD_FLAGS(_id, _name, _parents, \
  142. _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \
  143. _hwv_sta_ofs, _hwv_set_ofs, _hwv_clr_ofs, \
  144. _shift, _width, _gate, _upd_ofs, _upd, \
  145. _fenc_sta_mon_ofs, _fenc, 0)
  146. #define MUX_GATE_FENC_CLR_SET_UPD_FLAGS(_id, _name, _parents, _paridx, \
  147. _num_parents, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \
  148. _shift, _width, _gate, _upd_ofs, _upd, \
  149. _fenc_sta_mon_ofs, _fenc, _flags) { \
  150. .id = _id, \
  151. .name = _name, \
  152. .mux_ofs = _mux_ofs, \
  153. .set_ofs = _mux_set_ofs, \
  154. .clr_ofs = _mux_clr_ofs, \
  155. .upd_ofs = _upd_ofs, \
  156. .fenc_sta_mon_ofs = _fenc_sta_mon_ofs, \
  157. .mux_shift = _shift, \
  158. .mux_width = _width, \
  159. .gate_shift = _gate, \
  160. .upd_shift = _upd, \
  161. .fenc_shift = _fenc, \
  162. .parent_names = _parents, \
  163. .parent_index = _paridx, \
  164. .num_parents = _num_parents, \
  165. .flags = _flags, \
  166. .ops = &mtk_mux_gate_fenc_clr_set_upd_ops, \
  167. }
  168. #define MUX_GATE_FENC_CLR_SET_UPD(_id, _name, _parents, \
  169. _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \
  170. _shift, _width, _gate, _upd_ofs, _upd, \
  171. _fenc_sta_mon_ofs, _fenc) \
  172. MUX_GATE_FENC_CLR_SET_UPD_FLAGS(_id, _name, _parents, \
  173. NULL, ARRAY_SIZE(_parents), _mux_ofs, \
  174. _mux_set_ofs, _mux_clr_ofs, _shift, \
  175. _width, _gate, _upd_ofs, _upd, \
  176. _fenc_sta_mon_ofs, _fenc, 0)
  177. #define MUX_GATE_FENC_CLR_SET_UPD_INDEXED(_id, _name, _parents, _paridx, \
  178. _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \
  179. _shift, _width, _gate, _upd_ofs, _upd, \
  180. _fenc_sta_mon_ofs, _fenc) \
  181. MUX_GATE_FENC_CLR_SET_UPD_FLAGS(_id, _name, _parents, _paridx, \
  182. ARRAY_SIZE(_paridx), _mux_ofs, _mux_set_ofs, \
  183. _mux_clr_ofs, _shift, _width, _gate, _upd_ofs, _upd, \
  184. _fenc_sta_mon_ofs, _fenc, 0)
  185. int mtk_clk_register_muxes(struct device *dev,
  186. const struct mtk_mux *muxes,
  187. int num, struct device_node *node,
  188. spinlock_t *lock,
  189. struct clk_hw_onecell_data *clk_data);
  190. void mtk_clk_unregister_muxes(const struct mtk_mux *muxes, int num,
  191. struct clk_hw_onecell_data *clk_data);
  192. struct mtk_mux_nb {
  193. struct notifier_block nb;
  194. const struct clk_ops *ops;
  195. u8 bypass_index; /* Which parent to temporarily use */
  196. u8 original_index; /* Set by notifier callback */
  197. };
  198. #define to_mtk_mux_nb(_nb) container_of(_nb, struct mtk_mux_nb, nb)
  199. int devm_mtk_clk_mux_notifier_register(struct device *dev, struct clk *clk,
  200. struct mtk_mux_nb *mux_nb);
  201. #endif /* __DRV_CLK_MTK_MUX_H */