clk-sr.c 12 KB

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