clk-sr.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright 2017 Broadcom
  4. */
  5. #include <linux/err.h>
  6. #include <linux/clk-provider.h>
  7. #include <linux/of_device.h>
  8. #include <linux/platform_device.h>
  9. #include <dt-bindings/clock/bcm-sr.h>
  10. #include "clk-iproc.h"
  11. #define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, }
  12. #define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \
  13. .pwr_shift = ps, .iso_shift = is }
  14. #define SW_CTRL_VAL(o, s) { .offset = o, .shift = s, }
  15. #define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \
  16. .p_reset_shift = prs }
  17. #define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, \
  18. .ki_shift = kis, .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, \
  19. .ka_shift = kas, .ka_width = kaw }
  20. #define VCO_CTRL_VAL(uo, lo) { .u_offset = uo, .l_offset = lo }
  21. #define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \
  22. .hold_shift = hs, .bypass_shift = bs }
  23. static const struct iproc_pll_ctrl sr_genpll0 = {
  24. .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
  25. IPROC_CLK_PLL_NEEDS_SW_CFG,
  26. .aon = AON_VAL(0x0, 5, 1, 0),
  27. .reset = RESET_VAL(0x0, 12, 11),
  28. .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
  29. .sw_ctrl = SW_CTRL_VAL(0x10, 31),
  30. .ndiv_int = REG_VAL(0x10, 20, 10),
  31. .ndiv_frac = REG_VAL(0x10, 0, 20),
  32. .pdiv = REG_VAL(0x14, 0, 4),
  33. .status = REG_VAL(0x30, 12, 1),
  34. };
  35. static const struct iproc_clk_ctrl sr_genpll0_clk[] = {
  36. [BCM_SR_GENPLL0_125M_CLK] = {
  37. .channel = BCM_SR_GENPLL0_125M_CLK,
  38. .flags = IPROC_CLK_AON,
  39. .enable = ENABLE_VAL(0x4, 6, 0, 12),
  40. .mdiv = REG_VAL(0x18, 0, 9),
  41. },
  42. [BCM_SR_GENPLL0_SCR_CLK] = {
  43. .channel = BCM_SR_GENPLL0_SCR_CLK,
  44. .flags = IPROC_CLK_AON,
  45. .enable = ENABLE_VAL(0x4, 7, 1, 13),
  46. .mdiv = REG_VAL(0x18, 10, 9),
  47. },
  48. [BCM_SR_GENPLL0_250M_CLK] = {
  49. .channel = BCM_SR_GENPLL0_250M_CLK,
  50. .flags = IPROC_CLK_AON,
  51. .enable = ENABLE_VAL(0x4, 8, 2, 14),
  52. .mdiv = REG_VAL(0x18, 20, 9),
  53. },
  54. [BCM_SR_GENPLL0_PCIE_AXI_CLK] = {
  55. .channel = BCM_SR_GENPLL0_PCIE_AXI_CLK,
  56. .flags = IPROC_CLK_AON,
  57. .enable = ENABLE_VAL(0x4, 9, 3, 15),
  58. .mdiv = REG_VAL(0x1c, 0, 9),
  59. },
  60. [BCM_SR_GENPLL0_PAXC_AXI_X2_CLK] = {
  61. .channel = BCM_SR_GENPLL0_PAXC_AXI_X2_CLK,
  62. .flags = IPROC_CLK_AON,
  63. .enable = ENABLE_VAL(0x4, 10, 4, 16),
  64. .mdiv = REG_VAL(0x1c, 10, 9),
  65. },
  66. [BCM_SR_GENPLL0_PAXC_AXI_CLK] = {
  67. .channel = BCM_SR_GENPLL0_PAXC_AXI_CLK,
  68. .flags = IPROC_CLK_AON,
  69. .enable = ENABLE_VAL(0x4, 11, 5, 17),
  70. .mdiv = REG_VAL(0x1c, 20, 9),
  71. },
  72. };
  73. static int sr_genpll0_clk_init(struct platform_device *pdev)
  74. {
  75. iproc_pll_clk_setup(pdev->dev.of_node,
  76. &sr_genpll0, NULL, 0, sr_genpll0_clk,
  77. ARRAY_SIZE(sr_genpll0_clk));
  78. return 0;
  79. }
  80. static const struct iproc_pll_ctrl sr_genpll2 = {
  81. .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
  82. IPROC_CLK_PLL_NEEDS_SW_CFG,
  83. .aon = AON_VAL(0x0, 1, 13, 12),
  84. .reset = RESET_VAL(0x0, 12, 11),
  85. .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
  86. .sw_ctrl = SW_CTRL_VAL(0x10, 31),
  87. .ndiv_int = REG_VAL(0x10, 20, 10),
  88. .ndiv_frac = REG_VAL(0x10, 0, 20),
  89. .pdiv = REG_VAL(0x14, 0, 4),
  90. .status = REG_VAL(0x30, 12, 1),
  91. };
  92. static const struct iproc_clk_ctrl sr_genpll2_clk[] = {
  93. [BCM_SR_GENPLL2_NIC_CLK] = {
  94. .channel = BCM_SR_GENPLL2_NIC_CLK,
  95. .flags = IPROC_CLK_AON,
  96. .enable = ENABLE_VAL(0x4, 6, 0, 12),
  97. .mdiv = REG_VAL(0x18, 0, 9),
  98. },
  99. [BCM_SR_GENPLL2_TS_500_CLK] = {
  100. .channel = BCM_SR_GENPLL2_TS_500_CLK,
  101. .flags = IPROC_CLK_AON,
  102. .enable = ENABLE_VAL(0x4, 7, 1, 13),
  103. .mdiv = REG_VAL(0x18, 10, 9),
  104. },
  105. [BCM_SR_GENPLL2_125_NITRO_CLK] = {
  106. .channel = BCM_SR_GENPLL2_125_NITRO_CLK,
  107. .flags = IPROC_CLK_AON,
  108. .enable = ENABLE_VAL(0x4, 8, 2, 14),
  109. .mdiv = REG_VAL(0x18, 20, 9),
  110. },
  111. [BCM_SR_GENPLL2_CHIMP_CLK] = {
  112. .channel = BCM_SR_GENPLL2_CHIMP_CLK,
  113. .flags = IPROC_CLK_AON,
  114. .enable = ENABLE_VAL(0x4, 9, 3, 15),
  115. .mdiv = REG_VAL(0x1c, 0, 9),
  116. },
  117. [BCM_SR_GENPLL2_NIC_FLASH_CLK] = {
  118. .channel = BCM_SR_GENPLL2_NIC_FLASH_CLK,
  119. .flags = IPROC_CLK_AON,
  120. .enable = ENABLE_VAL(0x4, 10, 4, 16),
  121. .mdiv = REG_VAL(0x1c, 10, 9),
  122. },
  123. [BCM_SR_GENPLL2_FS4_CLK] = {
  124. .channel = BCM_SR_GENPLL2_FS4_CLK,
  125. .enable = ENABLE_VAL(0x4, 11, 5, 17),
  126. .mdiv = REG_VAL(0x1c, 20, 9),
  127. },
  128. };
  129. static int sr_genpll2_clk_init(struct platform_device *pdev)
  130. {
  131. iproc_pll_clk_setup(pdev->dev.of_node,
  132. &sr_genpll2, NULL, 0, sr_genpll2_clk,
  133. ARRAY_SIZE(sr_genpll2_clk));
  134. return 0;
  135. }
  136. static const struct iproc_pll_ctrl sr_genpll3 = {
  137. .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
  138. IPROC_CLK_PLL_NEEDS_SW_CFG,
  139. .aon = AON_VAL(0x0, 1, 19, 18),
  140. .reset = RESET_VAL(0x0, 12, 11),
  141. .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
  142. .sw_ctrl = SW_CTRL_VAL(0x10, 31),
  143. .ndiv_int = REG_VAL(0x10, 20, 10),
  144. .ndiv_frac = REG_VAL(0x10, 0, 20),
  145. .pdiv = REG_VAL(0x14, 0, 4),
  146. .status = REG_VAL(0x30, 12, 1),
  147. };
  148. static const struct iproc_clk_ctrl sr_genpll3_clk[] = {
  149. [BCM_SR_GENPLL3_HSLS_CLK] = {
  150. .channel = BCM_SR_GENPLL3_HSLS_CLK,
  151. .flags = IPROC_CLK_AON,
  152. .enable = ENABLE_VAL(0x4, 6, 0, 12),
  153. .mdiv = REG_VAL(0x18, 0, 9),
  154. },
  155. [BCM_SR_GENPLL3_SDIO_CLK] = {
  156. .channel = BCM_SR_GENPLL3_SDIO_CLK,
  157. .flags = IPROC_CLK_AON,
  158. .enable = ENABLE_VAL(0x4, 7, 1, 13),
  159. .mdiv = REG_VAL(0x18, 10, 9),
  160. },
  161. };
  162. static void sr_genpll3_clk_init(struct device_node *node)
  163. {
  164. iproc_pll_clk_setup(node, &sr_genpll3, NULL, 0, sr_genpll3_clk,
  165. ARRAY_SIZE(sr_genpll3_clk));
  166. }
  167. CLK_OF_DECLARE(sr_genpll3_clk, "brcm,sr-genpll3", sr_genpll3_clk_init);
  168. static const struct iproc_pll_ctrl sr_genpll4 = {
  169. .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
  170. IPROC_CLK_PLL_NEEDS_SW_CFG,
  171. .aon = AON_VAL(0x0, 1, 25, 24),
  172. .reset = RESET_VAL(0x0, 12, 11),
  173. .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
  174. .sw_ctrl = SW_CTRL_VAL(0x10, 31),
  175. .ndiv_int = REG_VAL(0x10, 20, 10),
  176. .ndiv_frac = REG_VAL(0x10, 0, 20),
  177. .pdiv = REG_VAL(0x14, 0, 4),
  178. .status = REG_VAL(0x30, 12, 1),
  179. };
  180. static const struct iproc_clk_ctrl sr_genpll4_clk[] = {
  181. [BCM_SR_GENPLL4_CCN_CLK] = {
  182. .channel = BCM_SR_GENPLL4_CCN_CLK,
  183. .flags = IPROC_CLK_AON,
  184. .enable = ENABLE_VAL(0x4, 6, 0, 12),
  185. .mdiv = REG_VAL(0x18, 0, 9),
  186. },
  187. [BCM_SR_GENPLL4_TPIU_PLL_CLK] = {
  188. .channel = BCM_SR_GENPLL4_TPIU_PLL_CLK,
  189. .flags = IPROC_CLK_AON,
  190. .enable = ENABLE_VAL(0x4, 7, 1, 13),
  191. .mdiv = REG_VAL(0x18, 10, 9),
  192. },
  193. [BCM_SR_GENPLL4_NOC_CLK] = {
  194. .channel = BCM_SR_GENPLL4_NOC_CLK,
  195. .flags = IPROC_CLK_AON,
  196. .enable = ENABLE_VAL(0x4, 8, 2, 14),
  197. .mdiv = REG_VAL(0x18, 20, 9),
  198. },
  199. [BCM_SR_GENPLL4_CHCLK_FS4_CLK] = {
  200. .channel = BCM_SR_GENPLL4_CHCLK_FS4_CLK,
  201. .flags = IPROC_CLK_AON,
  202. .enable = ENABLE_VAL(0x4, 9, 3, 15),
  203. .mdiv = REG_VAL(0x1c, 0, 9),
  204. },
  205. [BCM_SR_GENPLL4_BRIDGE_FSCPU_CLK] = {
  206. .channel = BCM_SR_GENPLL4_BRIDGE_FSCPU_CLK,
  207. .flags = IPROC_CLK_AON,
  208. .enable = ENABLE_VAL(0x4, 10, 4, 16),
  209. .mdiv = REG_VAL(0x1c, 10, 9),
  210. },
  211. };
  212. static int sr_genpll4_clk_init(struct platform_device *pdev)
  213. {
  214. iproc_pll_clk_setup(pdev->dev.of_node,
  215. &sr_genpll4, NULL, 0, sr_genpll4_clk,
  216. ARRAY_SIZE(sr_genpll4_clk));
  217. return 0;
  218. }
  219. static const struct iproc_pll_ctrl sr_genpll5 = {
  220. .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
  221. IPROC_CLK_PLL_NEEDS_SW_CFG,
  222. .aon = AON_VAL(0x0, 1, 1, 0),
  223. .reset = RESET_VAL(0x0, 12, 11),
  224. .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
  225. .sw_ctrl = SW_CTRL_VAL(0x10, 31),
  226. .ndiv_int = REG_VAL(0x10, 20, 10),
  227. .ndiv_frac = REG_VAL(0x10, 0, 20),
  228. .pdiv = REG_VAL(0x14, 0, 4),
  229. .status = REG_VAL(0x30, 12, 1),
  230. };
  231. static const struct iproc_clk_ctrl sr_genpll5_clk[] = {
  232. [BCM_SR_GENPLL5_FS4_HF_CLK] = {
  233. .channel = BCM_SR_GENPLL5_FS4_HF_CLK,
  234. .enable = ENABLE_VAL(0x4, 6, 0, 12),
  235. .mdiv = REG_VAL(0x18, 0, 9),
  236. },
  237. [BCM_SR_GENPLL5_CRYPTO_AE_CLK] = {
  238. .channel = BCM_SR_GENPLL5_CRYPTO_AE_CLK,
  239. .enable = ENABLE_VAL(0x4, 7, 1, 12),
  240. .mdiv = REG_VAL(0x18, 10, 9),
  241. },
  242. [BCM_SR_GENPLL5_RAID_AE_CLK] = {
  243. .channel = BCM_SR_GENPLL5_RAID_AE_CLK,
  244. .enable = ENABLE_VAL(0x4, 8, 2, 14),
  245. .mdiv = REG_VAL(0x18, 20, 9),
  246. },
  247. };
  248. static int sr_genpll5_clk_init(struct platform_device *pdev)
  249. {
  250. iproc_pll_clk_setup(pdev->dev.of_node,
  251. &sr_genpll5, NULL, 0, sr_genpll5_clk,
  252. ARRAY_SIZE(sr_genpll5_clk));
  253. return 0;
  254. }
  255. static const struct iproc_pll_ctrl sr_lcpll0 = {
  256. .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
  257. .aon = AON_VAL(0x0, 2, 19, 18),
  258. .reset = RESET_VAL(0x0, 31, 30),
  259. .sw_ctrl = SW_CTRL_VAL(0x4, 31),
  260. .ndiv_int = REG_VAL(0x4, 16, 10),
  261. .pdiv = REG_VAL(0x4, 26, 4),
  262. .status = REG_VAL(0x38, 12, 1),
  263. };
  264. static const struct iproc_clk_ctrl sr_lcpll0_clk[] = {
  265. [BCM_SR_LCPLL0_SATA_REFP_CLK] = {
  266. .channel = BCM_SR_LCPLL0_SATA_REFP_CLK,
  267. .flags = IPROC_CLK_AON,
  268. .enable = ENABLE_VAL(0x0, 7, 1, 13),
  269. .mdiv = REG_VAL(0x14, 0, 9),
  270. },
  271. [BCM_SR_LCPLL0_SATA_REFN_CLK] = {
  272. .channel = BCM_SR_LCPLL0_SATA_REFN_CLK,
  273. .flags = IPROC_CLK_AON,
  274. .enable = ENABLE_VAL(0x0, 8, 2, 14),
  275. .mdiv = REG_VAL(0x14, 10, 9),
  276. },
  277. [BCM_SR_LCPLL0_SATA_350_CLK] = {
  278. .channel = BCM_SR_LCPLL0_SATA_350_CLK,
  279. .flags = IPROC_CLK_AON,
  280. .enable = ENABLE_VAL(0x0, 9, 3, 15),
  281. .mdiv = REG_VAL(0x14, 20, 9),
  282. },
  283. [BCM_SR_LCPLL0_SATA_500_CLK] = {
  284. .channel = BCM_SR_LCPLL0_SATA_500_CLK,
  285. .flags = IPROC_CLK_AON,
  286. .enable = ENABLE_VAL(0x0, 10, 4, 16),
  287. .mdiv = REG_VAL(0x18, 0, 9),
  288. },
  289. };
  290. static int sr_lcpll0_clk_init(struct platform_device *pdev)
  291. {
  292. iproc_pll_clk_setup(pdev->dev.of_node,
  293. &sr_lcpll0, NULL, 0, sr_lcpll0_clk,
  294. ARRAY_SIZE(sr_lcpll0_clk));
  295. return 0;
  296. }
  297. static const struct iproc_pll_ctrl sr_lcpll1 = {
  298. .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
  299. .aon = AON_VAL(0x0, 2, 22, 21),
  300. .reset = RESET_VAL(0x0, 31, 30),
  301. .sw_ctrl = SW_CTRL_VAL(0x4, 31),
  302. .ndiv_int = REG_VAL(0x4, 16, 10),
  303. .pdiv = REG_VAL(0x4, 26, 4),
  304. .status = REG_VAL(0x38, 12, 1),
  305. };
  306. static const struct iproc_clk_ctrl sr_lcpll1_clk[] = {
  307. [BCM_SR_LCPLL1_WAN_CLK] = {
  308. .channel = BCM_SR_LCPLL1_WAN_CLK,
  309. .flags = IPROC_CLK_AON,
  310. .enable = ENABLE_VAL(0x0, 7, 1, 13),
  311. .mdiv = REG_VAL(0x14, 0, 9),
  312. },
  313. [BCM_SR_LCPLL1_USB_REF_CLK] = {
  314. .channel = BCM_SR_LCPLL1_USB_REF_CLK,
  315. .flags = IPROC_CLK_AON,
  316. .enable = ENABLE_VAL(0x0, 8, 2, 14),
  317. .mdiv = REG_VAL(0x14, 10, 9),
  318. },
  319. [BCM_SR_LCPLL1_CRMU_TS_CLK] = {
  320. .channel = BCM_SR_LCPLL1_CRMU_TS_CLK,
  321. .flags = IPROC_CLK_AON,
  322. .enable = ENABLE_VAL(0x0, 9, 3, 15),
  323. .mdiv = REG_VAL(0x14, 20, 9),
  324. },
  325. };
  326. static int sr_lcpll1_clk_init(struct platform_device *pdev)
  327. {
  328. iproc_pll_clk_setup(pdev->dev.of_node,
  329. &sr_lcpll1, NULL, 0, sr_lcpll1_clk,
  330. ARRAY_SIZE(sr_lcpll1_clk));
  331. return 0;
  332. }
  333. static const struct iproc_pll_ctrl sr_lcpll_pcie = {
  334. .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
  335. .aon = AON_VAL(0x0, 2, 25, 24),
  336. .reset = RESET_VAL(0x0, 31, 30),
  337. .sw_ctrl = SW_CTRL_VAL(0x4, 31),
  338. .ndiv_int = REG_VAL(0x4, 16, 10),
  339. .pdiv = REG_VAL(0x4, 26, 4),
  340. .status = REG_VAL(0x38, 12, 1),
  341. };
  342. static const struct iproc_clk_ctrl sr_lcpll_pcie_clk[] = {
  343. [BCM_SR_LCPLL_PCIE_PHY_REF_CLK] = {
  344. .channel = BCM_SR_LCPLL_PCIE_PHY_REF_CLK,
  345. .flags = IPROC_CLK_AON,
  346. .enable = ENABLE_VAL(0x0, 7, 1, 13),
  347. .mdiv = REG_VAL(0x14, 0, 9),
  348. },
  349. };
  350. static int sr_lcpll_pcie_clk_init(struct platform_device *pdev)
  351. {
  352. iproc_pll_clk_setup(pdev->dev.of_node,
  353. &sr_lcpll_pcie, NULL, 0, sr_lcpll_pcie_clk,
  354. ARRAY_SIZE(sr_lcpll_pcie_clk));
  355. return 0;
  356. }
  357. static const struct of_device_id sr_clk_dt_ids[] = {
  358. { .compatible = "brcm,sr-genpll0", .data = sr_genpll0_clk_init },
  359. { .compatible = "brcm,sr-genpll2", .data = sr_genpll2_clk_init },
  360. { .compatible = "brcm,sr-genpll4", .data = sr_genpll4_clk_init },
  361. { .compatible = "brcm,sr-genpll5", .data = sr_genpll5_clk_init },
  362. { .compatible = "brcm,sr-lcpll0", .data = sr_lcpll0_clk_init },
  363. { .compatible = "brcm,sr-lcpll1", .data = sr_lcpll1_clk_init },
  364. { .compatible = "brcm,sr-lcpll-pcie", .data = sr_lcpll_pcie_clk_init },
  365. { /* sentinel */ }
  366. };
  367. static int sr_clk_probe(struct platform_device *pdev)
  368. {
  369. int (*probe_func)(struct platform_device *);
  370. probe_func = of_device_get_match_data(&pdev->dev);
  371. if (!probe_func)
  372. return -ENODEV;
  373. return probe_func(pdev);
  374. }
  375. static struct platform_driver sr_clk_driver = {
  376. .driver = {
  377. .name = "sr-clk",
  378. .of_match_table = sr_clk_dt_ids,
  379. },
  380. .probe = sr_clk_probe,
  381. };
  382. builtin_platform_driver(sr_clk_driver);