clk-cv18xx-ip.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (C) 2023 Inochi Amaoto <inochiama@outlook.com>
  4. */
  5. #ifndef _CLK_SOPHGO_CV1800_IP_H_
  6. #define _CLK_SOPHGO_CV1800_IP_H_
  7. #include "clk-cv18xx-common.h"
  8. struct cv1800_clk_gate {
  9. struct cv1800_clk_common common;
  10. struct cv1800_clk_regbit gate;
  11. };
  12. struct cv1800_clk_div_data {
  13. u32 reg;
  14. u32 mask;
  15. u32 width;
  16. u32 init;
  17. u32 flags;
  18. };
  19. struct cv1800_clk_div {
  20. struct cv1800_clk_common common;
  21. struct cv1800_clk_regbit gate;
  22. struct cv1800_clk_regfield div;
  23. };
  24. struct cv1800_clk_bypass_div {
  25. struct cv1800_clk_div div;
  26. struct cv1800_clk_regbit bypass;
  27. };
  28. struct cv1800_clk_mux {
  29. struct cv1800_clk_common common;
  30. struct cv1800_clk_regbit gate;
  31. struct cv1800_clk_regfield div;
  32. struct cv1800_clk_regfield mux;
  33. };
  34. struct cv1800_clk_bypass_mux {
  35. struct cv1800_clk_mux mux;
  36. struct cv1800_clk_regbit bypass;
  37. };
  38. struct cv1800_clk_mmux {
  39. struct cv1800_clk_common common;
  40. struct cv1800_clk_regbit gate;
  41. struct cv1800_clk_regfield div[2];
  42. struct cv1800_clk_regfield mux[2];
  43. struct cv1800_clk_regbit bypass;
  44. struct cv1800_clk_regbit clk_sel;
  45. const s8 *parent2sel;
  46. const u8 *sel2parent[2];
  47. };
  48. struct cv1800_clk_audio {
  49. struct cv1800_clk_common common;
  50. struct cv1800_clk_regbit src_en;
  51. struct cv1800_clk_regbit output_en;
  52. struct cv1800_clk_regbit div_en;
  53. struct cv1800_clk_regbit div_up;
  54. struct cv1800_clk_regfield m;
  55. struct cv1800_clk_regfield n;
  56. u32 target_rate;
  57. };
  58. #define CV1800_GATE(_name, _parent, _gate_reg, _gate_shift, _flags) \
  59. struct cv1800_clk_gate _name = { \
  60. .common = CV1800_CLK_COMMON(#_name, _parent, \
  61. &cv1800_clk_gate_ops, \
  62. _flags), \
  63. .gate = CV1800_CLK_BIT(_gate_reg, _gate_shift), \
  64. }
  65. #define _CV1800_DIV(_name, _parent, _gate_reg, _gate_shift, \
  66. _div_reg, _div_shift, _div_width, _div_init, \
  67. _div_flag, _ops, _flags) \
  68. { \
  69. .common = CV1800_CLK_COMMON(#_name, _parent, \
  70. _ops, _flags), \
  71. .gate = CV1800_CLK_BIT(_gate_reg, \
  72. _gate_shift), \
  73. .div = CV1800_CLK_REG(_div_reg, _div_shift, \
  74. _div_width, _div_init, \
  75. _div_flag), \
  76. }
  77. #define _CV1800_FIXED_DIV_FLAG \
  78. (CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ROUND_CLOSEST)
  79. #define _CV1800_FIXED_DIV(_name, _parent, _gate_reg, _gate_shift, \
  80. _fix_div, _ops, _flags) \
  81. { \
  82. .common = CV1800_CLK_COMMON(#_name, _parent, \
  83. _ops, _flags), \
  84. .gate = CV1800_CLK_BIT(_gate_reg, \
  85. _gate_shift), \
  86. .div = CV1800_CLK_REG(0, 0, 0, \
  87. _fix_div, \
  88. _CV1800_FIXED_DIV_FLAG),\
  89. }
  90. #define CV1800_DIV(_name, _parent, _gate_reg, _gate_shift, \
  91. _div_reg, _div_shift, _div_width, _div_init, \
  92. _div_flag, _flags) \
  93. struct cv1800_clk_div _name = \
  94. _CV1800_DIV(_name, _parent, _gate_reg, _gate_shift, \
  95. _div_reg, _div_shift, _div_width, _div_init,\
  96. _div_flag, &cv1800_clk_div_ops, _flags)
  97. #define CV1800_BYPASS_DIV(_name, _parent, _gate_reg, _gate_shift, \
  98. _div_reg, _div_shift, _div_width, _div_init, \
  99. _div_flag, _bypass_reg, _bypass_shift, _flags)\
  100. struct cv1800_clk_bypass_div _name = { \
  101. .div = _CV1800_DIV(_name, _parent, \
  102. _gate_reg, _gate_shift, \
  103. _div_reg, _div_shift, \
  104. _div_width, _div_init, _div_flag, \
  105. &cv1800_clk_bypass_div_ops, \
  106. _flags), \
  107. .bypass = CV1800_CLK_BIT(_bypass_reg, _bypass_shift), \
  108. }
  109. #define CV1800_FIXED_DIV(_name, _parent, _gate_reg, _gate_shift, \
  110. _fix_div, _flags) \
  111. struct cv1800_clk_div _name = \
  112. _CV1800_FIXED_DIV(_name, _parent, \
  113. _gate_reg, _gate_shift, \
  114. _fix_div, \
  115. &cv1800_clk_div_ops, _flags) \
  116. #define CV1800_BYPASS_FIXED_DIV(_name, _parent, _gate_reg, _gate_shift, \
  117. _fix_div, _bypass_reg, _bypass_shift, \
  118. _flags) \
  119. struct cv1800_clk_bypass_div _name = { \
  120. .div = _CV1800_FIXED_DIV(_name, _parent, \
  121. _gate_reg, _gate_shift, \
  122. _fix_div, \
  123. &cv1800_clk_bypass_div_ops, \
  124. _flags), \
  125. .bypass = CV1800_CLK_BIT(_bypass_reg, _bypass_shift), \
  126. }
  127. #define _CV1800_MUX(_name, _parent, _gate_reg, _gate_shift, \
  128. _div_reg, _div_shift, _div_width, _div_init, \
  129. _div_flag, \
  130. _mux_reg, _mux_shift, _mux_width, \
  131. _ops, _flags) \
  132. { \
  133. .common = CV1800_CLK_COMMON(#_name, _parent, \
  134. _ops, _flags), \
  135. .gate = CV1800_CLK_BIT(_gate_reg, \
  136. _gate_shift), \
  137. .div = CV1800_CLK_REG(_div_reg, _div_shift, \
  138. _div_width, _div_init, \
  139. _div_flag), \
  140. .mux = CV1800_CLK_REG(_mux_reg, _mux_shift, \
  141. _mux_width, 0, 0), \
  142. }
  143. #define CV1800_MUX(_name, _parent, _gate_reg, _gate_shift, \
  144. _div_reg, _div_shift, _div_width, _div_init, \
  145. _div_flag, \
  146. _mux_reg, _mux_shift, _mux_width, _flags) \
  147. struct cv1800_clk_mux _name = \
  148. _CV1800_MUX(_name, _parent, _gate_reg, _gate_shift, \
  149. _div_reg, _div_shift, _div_width, _div_init,\
  150. _div_flag, _mux_reg, _mux_shift, _mux_width,\
  151. &cv1800_clk_mux_ops, _flags)
  152. #define CV1800_BYPASS_MUX(_name, _parent, _gate_reg, _gate_shift, \
  153. _div_reg, _div_shift, _div_width, _div_init, \
  154. _div_flag, \
  155. _mux_reg, _mux_shift, _mux_width, \
  156. _bypass_reg, _bypass_shift, _flags) \
  157. struct cv1800_clk_bypass_mux _name = { \
  158. .mux = _CV1800_MUX(_name, _parent, \
  159. _gate_reg, _gate_shift, \
  160. _div_reg, _div_shift, _div_width, \
  161. _div_init, _div_flag, \
  162. _mux_reg, _mux_shift, _mux_width, \
  163. &cv1800_clk_bypass_mux_ops, \
  164. _flags), \
  165. .bypass = CV1800_CLK_BIT(_bypass_reg, _bypass_shift), \
  166. }
  167. #define CV1800_MMUX(_name, _parent, _gate_reg, _gate_shift, \
  168. _div0_reg, _div0_shift, _div0_width, _div0_init, \
  169. _div0_flag, \
  170. _div1_reg, _div1_shift, _div1_width, _div1_init, \
  171. _div1_flag, \
  172. _mux0_reg, _mux0_shift, _mux0_width, \
  173. _mux1_reg, _mux1_shift, _mux1_width, \
  174. _bypass_reg, _bypass_shift, \
  175. _clk_sel_reg, _clk_sel_shift, \
  176. _parent2sel, _sel2parent0, _sel2parent1, _flags) \
  177. struct cv1800_clk_mmux _name = { \
  178. .common = CV1800_CLK_COMMON(#_name, _parent, \
  179. &cv1800_clk_mmux_ops,\
  180. _flags), \
  181. .gate = CV1800_CLK_BIT(_gate_reg, _gate_shift),\
  182. .div = { \
  183. CV1800_CLK_REG(_div0_reg, _div0_shift, \
  184. _div0_width, _div0_init, \
  185. _div0_flag), \
  186. CV1800_CLK_REG(_div1_reg, _div1_shift, \
  187. _div1_width, _div1_init, \
  188. _div1_flag), \
  189. }, \
  190. .mux = { \
  191. CV1800_CLK_REG(_mux0_reg, _mux0_shift, \
  192. _mux0_width, 0, 0), \
  193. CV1800_CLK_REG(_mux1_reg, _mux1_shift, \
  194. _mux1_width, 0, 0), \
  195. }, \
  196. .bypass = CV1800_CLK_BIT(_bypass_reg, \
  197. _bypass_shift), \
  198. .clk_sel = CV1800_CLK_BIT(_clk_sel_reg, \
  199. _clk_sel_shift), \
  200. .parent2sel = _parent2sel, \
  201. .sel2parent = { _sel2parent0, _sel2parent1 }, \
  202. }
  203. #define CV1800_ACLK(_name, _parent, \
  204. _src_en_reg, _src_en_reg_shift, \
  205. _output_en_reg, _output_en_shift, \
  206. _div_en_reg, _div_en_reg_shift, \
  207. _div_up_reg, _div_up_reg_shift, \
  208. _m_reg, _m_shift, _m_width, _m_flag, \
  209. _n_reg, _n_shift, _n_width, _n_flag, \
  210. _target_rate, _flags) \
  211. struct cv1800_clk_audio _name = { \
  212. .common = CV1800_CLK_COMMON(#_name, _parent, \
  213. &cv1800_clk_audio_ops,\
  214. _flags), \
  215. .src_en = CV1800_CLK_BIT(_src_en_reg, \
  216. _src_en_reg_shift), \
  217. .output_en = CV1800_CLK_BIT(_output_en_reg, \
  218. _output_en_shift), \
  219. .div_en = CV1800_CLK_BIT(_div_en_reg, \
  220. _div_en_reg_shift), \
  221. .div_up = CV1800_CLK_BIT(_div_up_reg, \
  222. _div_up_reg_shift), \
  223. .m = CV1800_CLK_REG(_m_reg, _m_shift, \
  224. _m_width, 0, _m_flag), \
  225. .n = CV1800_CLK_REG(_n_reg, _n_shift, \
  226. _n_width, 0, _n_flag), \
  227. .target_rate = _target_rate, \
  228. }
  229. extern const struct clk_ops cv1800_clk_gate_ops;
  230. extern const struct clk_ops cv1800_clk_div_ops;
  231. extern const struct clk_ops cv1800_clk_bypass_div_ops;
  232. extern const struct clk_ops cv1800_clk_mux_ops;
  233. extern const struct clk_ops cv1800_clk_bypass_mux_ops;
  234. extern const struct clk_ops cv1800_clk_mmux_ops;
  235. extern const struct clk_ops cv1800_clk_audio_ops;
  236. #endif // _CLK_SOPHGO_CV1800_IP_H_