sifive-prci.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (C) 2018-2019 SiFive, Inc.
  4. * Wesley Terpstra
  5. * Paul Walmsley
  6. * Zong Li
  7. */
  8. #ifndef __SIFIVE_CLK_SIFIVE_PRCI_H
  9. #define __SIFIVE_CLK_SIFIVE_PRCI_H
  10. #include <linux/clk/analogbits-wrpll-cln28hpc.h>
  11. #include <linux/clk-provider.h>
  12. #include <linux/reset/reset-simple.h>
  13. #include <linux/platform_device.h>
  14. /*
  15. * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects:
  16. * hfclk and rtcclk
  17. */
  18. #define EXPECTED_CLK_PARENT_COUNT 2
  19. /*
  20. * Register offsets and bitmasks
  21. */
  22. /* COREPLLCFG0 */
  23. #define PRCI_COREPLLCFG0_OFFSET 0x4
  24. #define PRCI_COREPLLCFG0_DIVR_SHIFT 0
  25. #define PRCI_COREPLLCFG0_DIVR_MASK (0x3f << PRCI_COREPLLCFG0_DIVR_SHIFT)
  26. #define PRCI_COREPLLCFG0_DIVF_SHIFT 6
  27. #define PRCI_COREPLLCFG0_DIVF_MASK (0x1ff << PRCI_COREPLLCFG0_DIVF_SHIFT)
  28. #define PRCI_COREPLLCFG0_DIVQ_SHIFT 15
  29. #define PRCI_COREPLLCFG0_DIVQ_MASK (0x7 << PRCI_COREPLLCFG0_DIVQ_SHIFT)
  30. #define PRCI_COREPLLCFG0_RANGE_SHIFT 18
  31. #define PRCI_COREPLLCFG0_RANGE_MASK (0x7 << PRCI_COREPLLCFG0_RANGE_SHIFT)
  32. #define PRCI_COREPLLCFG0_BYPASS_SHIFT 24
  33. #define PRCI_COREPLLCFG0_BYPASS_MASK (0x1 << PRCI_COREPLLCFG0_BYPASS_SHIFT)
  34. #define PRCI_COREPLLCFG0_FSE_SHIFT 25
  35. #define PRCI_COREPLLCFG0_FSE_MASK (0x1 << PRCI_COREPLLCFG0_FSE_SHIFT)
  36. #define PRCI_COREPLLCFG0_LOCK_SHIFT 31
  37. #define PRCI_COREPLLCFG0_LOCK_MASK (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT)
  38. /* COREPLLCFG1 */
  39. #define PRCI_COREPLLCFG1_OFFSET 0x8
  40. #define PRCI_COREPLLCFG1_CKE_SHIFT 31
  41. #define PRCI_COREPLLCFG1_CKE_MASK (0x1 << PRCI_COREPLLCFG1_CKE_SHIFT)
  42. /* DDRPLLCFG0 */
  43. #define PRCI_DDRPLLCFG0_OFFSET 0xc
  44. #define PRCI_DDRPLLCFG0_DIVR_SHIFT 0
  45. #define PRCI_DDRPLLCFG0_DIVR_MASK (0x3f << PRCI_DDRPLLCFG0_DIVR_SHIFT)
  46. #define PRCI_DDRPLLCFG0_DIVF_SHIFT 6
  47. #define PRCI_DDRPLLCFG0_DIVF_MASK (0x1ff << PRCI_DDRPLLCFG0_DIVF_SHIFT)
  48. #define PRCI_DDRPLLCFG0_DIVQ_SHIFT 15
  49. #define PRCI_DDRPLLCFG0_DIVQ_MASK (0x7 << PRCI_DDRPLLCFG0_DIVQ_SHIFT)
  50. #define PRCI_DDRPLLCFG0_RANGE_SHIFT 18
  51. #define PRCI_DDRPLLCFG0_RANGE_MASK (0x7 << PRCI_DDRPLLCFG0_RANGE_SHIFT)
  52. #define PRCI_DDRPLLCFG0_BYPASS_SHIFT 24
  53. #define PRCI_DDRPLLCFG0_BYPASS_MASK (0x1 << PRCI_DDRPLLCFG0_BYPASS_SHIFT)
  54. #define PRCI_DDRPLLCFG0_FSE_SHIFT 25
  55. #define PRCI_DDRPLLCFG0_FSE_MASK (0x1 << PRCI_DDRPLLCFG0_FSE_SHIFT)
  56. #define PRCI_DDRPLLCFG0_LOCK_SHIFT 31
  57. #define PRCI_DDRPLLCFG0_LOCK_MASK (0x1 << PRCI_DDRPLLCFG0_LOCK_SHIFT)
  58. /* DDRPLLCFG1 */
  59. #define PRCI_DDRPLLCFG1_OFFSET 0x10
  60. #define PRCI_DDRPLLCFG1_CKE_SHIFT 31
  61. #define PRCI_DDRPLLCFG1_CKE_MASK (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
  62. /* PCIEAUX */
  63. #define PRCI_PCIE_AUX_OFFSET 0x14
  64. #define PRCI_PCIE_AUX_EN_SHIFT 0
  65. #define PRCI_PCIE_AUX_EN_MASK (0x1 << PRCI_PCIE_AUX_EN_SHIFT)
  66. /* GEMGXLPLLCFG0 */
  67. #define PRCI_GEMGXLPLLCFG0_OFFSET 0x1c
  68. #define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT 0
  69. #define PRCI_GEMGXLPLLCFG0_DIVR_MASK (0x3f << PRCI_GEMGXLPLLCFG0_DIVR_SHIFT)
  70. #define PRCI_GEMGXLPLLCFG0_DIVF_SHIFT 6
  71. #define PRCI_GEMGXLPLLCFG0_DIVF_MASK (0x1ff << PRCI_GEMGXLPLLCFG0_DIVF_SHIFT)
  72. #define PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT 15
  73. #define PRCI_GEMGXLPLLCFG0_DIVQ_MASK (0x7 << PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT)
  74. #define PRCI_GEMGXLPLLCFG0_RANGE_SHIFT 18
  75. #define PRCI_GEMGXLPLLCFG0_RANGE_MASK (0x7 << PRCI_GEMGXLPLLCFG0_RANGE_SHIFT)
  76. #define PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT 24
  77. #define PRCI_GEMGXLPLLCFG0_BYPASS_MASK (0x1 << PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT)
  78. #define PRCI_GEMGXLPLLCFG0_FSE_SHIFT 25
  79. #define PRCI_GEMGXLPLLCFG0_FSE_MASK (0x1 << PRCI_GEMGXLPLLCFG0_FSE_SHIFT)
  80. #define PRCI_GEMGXLPLLCFG0_LOCK_SHIFT 31
  81. #define PRCI_GEMGXLPLLCFG0_LOCK_MASK (0x1 << PRCI_GEMGXLPLLCFG0_LOCK_SHIFT)
  82. /* GEMGXLPLLCFG1 */
  83. #define PRCI_GEMGXLPLLCFG1_OFFSET 0x20
  84. #define PRCI_GEMGXLPLLCFG1_CKE_SHIFT 31
  85. #define PRCI_GEMGXLPLLCFG1_CKE_MASK (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
  86. /* CORECLKSEL */
  87. #define PRCI_CORECLKSEL_OFFSET 0x24
  88. #define PRCI_CORECLKSEL_CORECLKSEL_SHIFT 0
  89. #define PRCI_CORECLKSEL_CORECLKSEL_MASK \
  90. (0x1 << PRCI_CORECLKSEL_CORECLKSEL_SHIFT)
  91. /* DEVICESRESETREG */
  92. #define PRCI_DEVICESRESETREG_OFFSET 0x28
  93. #define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT 0
  94. #define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK \
  95. (0x1 << PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT)
  96. #define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT 1
  97. #define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK \
  98. (0x1 << PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT)
  99. #define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT 2
  100. #define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK \
  101. (0x1 << PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT)
  102. #define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT 3
  103. #define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK \
  104. (0x1 << PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT)
  105. #define PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT 5
  106. #define PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK \
  107. (0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT)
  108. #define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT 6
  109. #define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_MASK \
  110. (0x1 << PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT)
  111. #define PRCI_RST_NR 7
  112. /* CLKMUXSTATUSREG */
  113. #define PRCI_CLKMUXSTATUSREG_OFFSET 0x2c
  114. #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1
  115. #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK \
  116. (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
  117. /* CLTXPLLCFG0 */
  118. #define PRCI_CLTXPLLCFG0_OFFSET 0x30
  119. #define PRCI_CLTXPLLCFG0_DIVR_SHIFT 0
  120. #define PRCI_CLTXPLLCFG0_DIVR_MASK (0x3f << PRCI_CLTXPLLCFG0_DIVR_SHIFT)
  121. #define PRCI_CLTXPLLCFG0_DIVF_SHIFT 6
  122. #define PRCI_CLTXPLLCFG0_DIVF_MASK (0x1ff << PRCI_CLTXPLLCFG0_DIVF_SHIFT)
  123. #define PRCI_CLTXPLLCFG0_DIVQ_SHIFT 15
  124. #define PRCI_CLTXPLLCFG0_DIVQ_MASK (0x7 << PRCI_CLTXPLLCFG0_DIVQ_SHIFT)
  125. #define PRCI_CLTXPLLCFG0_RANGE_SHIFT 18
  126. #define PRCI_CLTXPLLCFG0_RANGE_MASK (0x7 << PRCI_CLTXPLLCFG0_RANGE_SHIFT)
  127. #define PRCI_CLTXPLLCFG0_BYPASS_SHIFT 24
  128. #define PRCI_CLTXPLLCFG0_BYPASS_MASK (0x1 << PRCI_CLTXPLLCFG0_BYPASS_SHIFT)
  129. #define PRCI_CLTXPLLCFG0_FSE_SHIFT 25
  130. #define PRCI_CLTXPLLCFG0_FSE_MASK (0x1 << PRCI_CLTXPLLCFG0_FSE_SHIFT)
  131. #define PRCI_CLTXPLLCFG0_LOCK_SHIFT 31
  132. #define PRCI_CLTXPLLCFG0_LOCK_MASK (0x1 << PRCI_CLTXPLLCFG0_LOCK_SHIFT)
  133. /* CLTXPLLCFG1 */
  134. #define PRCI_CLTXPLLCFG1_OFFSET 0x34
  135. #define PRCI_CLTXPLLCFG1_CKE_SHIFT 31
  136. #define PRCI_CLTXPLLCFG1_CKE_MASK (0x1 << PRCI_CLTXPLLCFG1_CKE_SHIFT)
  137. /* DVFSCOREPLLCFG0 */
  138. #define PRCI_DVFSCOREPLLCFG0_OFFSET 0x38
  139. /* DVFSCOREPLLCFG1 */
  140. #define PRCI_DVFSCOREPLLCFG1_OFFSET 0x3c
  141. #define PRCI_DVFSCOREPLLCFG1_CKE_SHIFT 31
  142. #define PRCI_DVFSCOREPLLCFG1_CKE_MASK (0x1 << PRCI_DVFSCOREPLLCFG1_CKE_SHIFT)
  143. /* COREPLLSEL */
  144. #define PRCI_COREPLLSEL_OFFSET 0x40
  145. #define PRCI_COREPLLSEL_COREPLLSEL_SHIFT 0
  146. #define PRCI_COREPLLSEL_COREPLLSEL_MASK \
  147. (0x1 << PRCI_COREPLLSEL_COREPLLSEL_SHIFT)
  148. /* HFPCLKPLLCFG0 */
  149. #define PRCI_HFPCLKPLLCFG0_OFFSET 0x50
  150. #define PRCI_HFPCLKPLL_CFG0_DIVR_SHIFT 0
  151. #define PRCI_HFPCLKPLL_CFG0_DIVR_MASK \
  152. (0x3f << PRCI_HFPCLKPLLCFG0_DIVR_SHIFT)
  153. #define PRCI_HFPCLKPLL_CFG0_DIVF_SHIFT 6
  154. #define PRCI_HFPCLKPLL_CFG0_DIVF_MASK \
  155. (0x1ff << PRCI_HFPCLKPLLCFG0_DIVF_SHIFT)
  156. #define PRCI_HFPCLKPLL_CFG0_DIVQ_SHIFT 15
  157. #define PRCI_HFPCLKPLL_CFG0_DIVQ_MASK \
  158. (0x7 << PRCI_HFPCLKPLLCFG0_DIVQ_SHIFT)
  159. #define PRCI_HFPCLKPLL_CFG0_RANGE_SHIFT 18
  160. #define PRCI_HFPCLKPLL_CFG0_RANGE_MASK \
  161. (0x7 << PRCI_HFPCLKPLLCFG0_RANGE_SHIFT)
  162. #define PRCI_HFPCLKPLL_CFG0_BYPASS_SHIFT 24
  163. #define PRCI_HFPCLKPLL_CFG0_BYPASS_MASK \
  164. (0x1 << PRCI_HFPCLKPLLCFG0_BYPASS_SHIFT)
  165. #define PRCI_HFPCLKPLL_CFG0_FSE_SHIFT 25
  166. #define PRCI_HFPCLKPLL_CFG0_FSE_MASK \
  167. (0x1 << PRCI_HFPCLKPLLCFG0_FSE_SHIFT)
  168. #define PRCI_HFPCLKPLL_CFG0_LOCK_SHIFT 31
  169. #define PRCI_HFPCLKPLL_CFG0_LOCK_MASK \
  170. (0x1 << PRCI_HFPCLKPLLCFG0_LOCK_SHIFT)
  171. /* HFPCLKPLLCFG1 */
  172. #define PRCI_HFPCLKPLLCFG1_OFFSET 0x54
  173. #define PRCI_HFPCLKPLLCFG1_CKE_SHIFT 31
  174. #define PRCI_HFPCLKPLLCFG1_CKE_MASK \
  175. (0x1 << PRCI_HFPCLKPLLCFG1_CKE_SHIFT)
  176. /* HFPCLKPLLSEL */
  177. #define PRCI_HFPCLKPLLSEL_OFFSET 0x58
  178. #define PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_SHIFT 0
  179. #define PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_MASK \
  180. (0x1 << PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_SHIFT)
  181. /* HFPCLKPLLDIV */
  182. #define PRCI_HFPCLKPLLDIV_OFFSET 0x5c
  183. /* PRCIPLL */
  184. #define PRCI_PRCIPLL_OFFSET 0xe0
  185. /* PROCMONCFG */
  186. #define PRCI_PROCMONCFG_OFFSET 0xf0
  187. /*
  188. * Private structures
  189. */
  190. /**
  191. * struct __prci_data - per-device-instance data
  192. * @va: base virtual address of the PRCI IP block
  193. * @hw_clks: encapsulates struct clk_hw records
  194. *
  195. * PRCI per-device instance data
  196. */
  197. struct __prci_data {
  198. void __iomem *va;
  199. struct reset_simple_data reset;
  200. struct clk_hw_onecell_data hw_clks;
  201. };
  202. /**
  203. * struct __prci_wrpll_data - WRPLL configuration and integration data
  204. * @c: WRPLL current configuration record
  205. * @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL)
  206. * @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL)
  207. * @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address
  208. * @cfg1_offs: WRPLL CFG1 register offset (in bytes) from the PRCI base address
  209. *
  210. * @enable_bypass and @disable_bypass are used for WRPLL instances
  211. * that contain a separate external glitchless clock mux downstream
  212. * from the PLL. The WRPLL internal bypass mux is not glitchless.
  213. */
  214. struct __prci_wrpll_data {
  215. struct wrpll_cfg c;
  216. void (*enable_bypass)(struct __prci_data *pd);
  217. void (*disable_bypass)(struct __prci_data *pd);
  218. u8 cfg0_offs;
  219. u8 cfg1_offs;
  220. };
  221. /**
  222. * struct __prci_clock - describes a clock device managed by PRCI
  223. * @name: user-readable clock name string - should match the manual
  224. * @parent_name: parent name for this clock
  225. * @ops: struct clk_ops for the Linux clock framework to use for control
  226. * @hw: Linux-private clock data
  227. * @pwd: WRPLL-specific data, associated with this clock (if not NULL)
  228. * @pd: PRCI-specific data associated with this clock (if not NULL)
  229. *
  230. * PRCI clock data. Used by the PRCI driver to register PRCI-provided
  231. * clocks to the Linux clock infrastructure.
  232. */
  233. struct __prci_clock {
  234. const char *name;
  235. const char *parent_name;
  236. const struct clk_ops *ops;
  237. struct clk_hw hw;
  238. struct __prci_wrpll_data *pwd;
  239. struct __prci_data *pd;
  240. };
  241. #define clk_hw_to_prci_clock(pwd) container_of(pwd, struct __prci_clock, hw)
  242. /*
  243. * struct prci_clk_desc - describes the information of clocks of each SoCs
  244. * @clks: point to a array of __prci_clock
  245. * @num_clks: the number of element of clks
  246. */
  247. struct prci_clk_desc {
  248. struct __prci_clock *clks;
  249. size_t num_clks;
  250. };
  251. /* Core clock mux control */
  252. void sifive_prci_coreclksel_use_hfclk(struct __prci_data *pd);
  253. void sifive_prci_coreclksel_use_corepll(struct __prci_data *pd);
  254. void sifive_prci_coreclksel_use_final_corepll(struct __prci_data *pd);
  255. void sifive_prci_corepllsel_use_dvfscorepll(struct __prci_data *pd);
  256. void sifive_prci_corepllsel_use_corepll(struct __prci_data *pd);
  257. void sifive_prci_hfpclkpllsel_use_hfclk(struct __prci_data *pd);
  258. void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd);
  259. /* Linux clock framework integration */
  260. long sifive_prci_wrpll_round_rate(struct clk_hw *hw, unsigned long rate,
  261. unsigned long *parent_rate);
  262. int sifive_prci_wrpll_set_rate(struct clk_hw *hw, unsigned long rate,
  263. unsigned long parent_rate);
  264. int sifive_clk_is_enabled(struct clk_hw *hw);
  265. int sifive_prci_clock_enable(struct clk_hw *hw);
  266. void sifive_prci_clock_disable(struct clk_hw *hw);
  267. unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw,
  268. unsigned long parent_rate);
  269. unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
  270. unsigned long parent_rate);
  271. unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
  272. unsigned long parent_rate);
  273. int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw);
  274. int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw);
  275. void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw);
  276. #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */