pll.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2022-2023 StarFive Technology Co., Ltd.
  4. * Author: yanhong <yanhong.wang@starfivetech.com>
  5. * samin <samin.guo@starfivetech.com>
  6. */
  7. #include <common.h>
  8. #include <asm/io.h>
  9. #include <asm/arch/clk.h>
  10. #include <asm/arch/jh7110-regs.h>
  11. #include <linux/bitops.h>
  12. #include <log.h>
  13. #define PLL0_DACPD_MASK BIT(24)
  14. #define PLL0_DSMPD_MASK BIT(25)
  15. #define PLL0_FBDIV_MASK GENMASK(11, 0)
  16. #define PLL0_FRAC_MASK GENMASK(23, 0)
  17. #define PLL0_PD_MASK BIT(27)
  18. #define PLL0_POSTDIV1_MASK GENMASK(29, 28)
  19. #define PLL0_PREDIV_MASK GENMASK(5, 0)
  20. #define PLL1_DACPD_MASK BIT(15)
  21. #define PLL1_DSMPD_MASK BIT(16)
  22. #define PLL1_FBDIV_MASK GENMASK(28, 17)
  23. #define PLL1_FRAC_MASK GENMASK(23, 0)
  24. #define PLL1_PD_MASK BIT(27)
  25. #define PLL1_POSTDIV1_MASK GENMASK(29, 28)
  26. #define PLL1_PREDIV_MASK GENMASK(5, 0)
  27. #define PLL2_DACPD_MASK BIT(15)
  28. #define PLL2_DSMPD_MASK BIT(16)
  29. #define PLL2_FBDIV_MASK GENMASK(28, 17)
  30. #define PLL2_FRAC_MASK GENMASK(23, 0)
  31. #define PLL2_PD_MASK BIT(27)
  32. #define PLL2_POSTDIV1_MASK GENMASK(29, 28)
  33. #define PLL2_PREDIV_MASK GENMASK(5, 0)
  34. #define PLL0_DACPD_OFFSET 0x18
  35. #define PLL0_DSMPD_OFFSET 0x18
  36. #define PLL0_FBDIV_OFFSET 0x1C
  37. #define PLL0_FRAC_OFFSET 0x20
  38. #define PLL0_PD_OFFSET 0x20
  39. #define PLL0_POSTDIV1_OFFSET 0x20
  40. #define PLL0_PREDIV_OFFSET 0x24
  41. #define PLL1_DACPD_OFFSET 0x24
  42. #define PLL1_DSMPD_OFFSET 0x24
  43. #define PLL1_FBDIV_OFFSET 0x24
  44. #define PLL1_FRAC_OFFSET 0x28
  45. #define PLL1_PD_OFFSET 0x28
  46. #define PLL1_POSTDIV1_OFFSET 0x28
  47. #define PLL1_PREDIV_OFFSET 0x2c
  48. #define PLL2_DACPD_OFFSET 0x2c
  49. #define PLL2_DSMPD_OFFSET 0x2c
  50. #define PLL2_FBDIV_OFFSET 0x2c
  51. #define PLL2_FRAC_OFFSET 0x30
  52. #define PLL2_PD_OFFSET 0x30
  53. #define PLL2_POSTDIV1_OFFSET 0x30
  54. #define PLL2_PREDIV_OFFSET 0x34
  55. #define PLL_PD_OFF 1
  56. #define PLL_PD_ON 0
  57. struct starfive_pll_freq jh7110_pll0_freq[] = {
  58. {
  59. .freq = 375000000,
  60. .prediv = 8,
  61. .fbdiv = 125,
  62. .postdiv1 = 1,
  63. .dacpd = 1,
  64. .dsmpd = 1
  65. },
  66. {
  67. .freq = 500000000,
  68. .prediv = 6,
  69. .fbdiv = 125,
  70. .postdiv1 = 1,
  71. .dacpd = 1,
  72. .dsmpd = 1
  73. },
  74. {
  75. .freq = 625000000,
  76. .prediv = 24,
  77. .fbdiv = 625,
  78. .postdiv1 = 1,
  79. .dacpd = 1,
  80. .dsmpd = 1
  81. },
  82. {
  83. .freq = 750000000,
  84. .prediv = 4,
  85. .fbdiv = 125,
  86. .postdiv1 = 1,
  87. .dacpd = 1,
  88. .dsmpd = 1
  89. },
  90. {
  91. .freq = 875000000,
  92. .prediv = 24,
  93. .fbdiv = 875,
  94. .postdiv1 = 1,
  95. .dacpd = 1,
  96. .dsmpd = 1
  97. },
  98. {
  99. .freq = 1000000000,
  100. .prediv = 3,
  101. .fbdiv = 125,
  102. .postdiv1 = 1,
  103. .dacpd = 1,
  104. .dsmpd = 1
  105. },
  106. {
  107. .freq = 1250000000,
  108. .prediv = 12,
  109. .fbdiv = 625,
  110. .postdiv1 = 1,
  111. .dacpd = 1,
  112. .dsmpd = 1
  113. },
  114. {
  115. .freq = 1375000000,
  116. .prediv = 24,
  117. .fbdiv = 1375,
  118. .postdiv1 = 1,
  119. .dacpd = 1,
  120. .dsmpd = 1
  121. },
  122. {
  123. .freq = 1500000000,
  124. .prediv = 2,
  125. .fbdiv = 125,
  126. .postdiv1 = 1,
  127. .dacpd = 1,
  128. .dsmpd = 1
  129. },
  130. {
  131. .freq = 1625000000,
  132. .prediv = 24,
  133. .fbdiv = 1625,
  134. .postdiv1 = 1,
  135. .dacpd = 1,
  136. .dsmpd = 1
  137. },
  138. {
  139. .freq = 1750000000,
  140. .prediv = 12,
  141. .fbdiv = 875,
  142. .postdiv1 = 1,
  143. .dacpd = 1,
  144. .dsmpd = 1
  145. },
  146. {
  147. .freq = 1800000000,
  148. .prediv = 3,
  149. .fbdiv = 225,
  150. .postdiv1 = 1,
  151. .dacpd = 1,
  152. .dsmpd = 1
  153. },
  154. };
  155. struct starfive_pll_freq jh7110_pll1_freq[] = {
  156. {
  157. .freq = 1066000000,
  158. .prediv = 12,
  159. .fbdiv = 533,
  160. .postdiv1 = 1,
  161. .dacpd = 1,
  162. .dsmpd = 1
  163. },
  164. {
  165. .freq = 1200000000,
  166. .prediv = 1,
  167. .fbdiv = 50,
  168. .postdiv1 = 1,
  169. .dacpd = 1,
  170. .dsmpd = 1
  171. },
  172. {
  173. .freq = 1400000000,
  174. .prediv = 6,
  175. .fbdiv = 350,
  176. .postdiv1 = 1,
  177. .dacpd = 1,
  178. .dsmpd = 1
  179. },
  180. {
  181. .freq = 1600000000,
  182. .prediv = 3,
  183. .fbdiv = 200,
  184. .postdiv1 = 1,
  185. .dacpd = 1,
  186. .dsmpd = 1
  187. },
  188. };
  189. struct starfive_pll_freq jh7110_pll2_freq[] = {
  190. {
  191. .freq = 1228800000,
  192. .prediv = 15,
  193. .fbdiv = 768,
  194. .postdiv1 = 1,
  195. .dacpd = 1,
  196. .dsmpd = 1
  197. },
  198. {
  199. .freq = 1188000000,
  200. .prediv = 2,
  201. .fbdiv = 99,
  202. .postdiv1 = 1,
  203. .dacpd = 1,
  204. .dsmpd = 1
  205. },
  206. };
  207. #define getbits_le32(addr, mask) ((in_le32(addr)&(mask)) >> __ffs(mask))
  208. #define GET_PLL(index, type) \
  209. getbits_le32(SYS_SYSCON_BASE + index##_##type##_OFFSET, index##_##type##_MASK)
  210. #define SET_PLL(index, type, val) \
  211. clrsetbits_le32(SYS_SYSCON_BASE + index##_##type##_OFFSET, \
  212. index##_##type##_MASK, \
  213. ((val) << __ffs(index##_##type##_MASK)) & index##_##type##_MASK)
  214. static void pll_set_rate(enum starfive_pll_type pll,
  215. struct starfive_pll_freq *freq)
  216. {
  217. switch (pll) {
  218. case PLL0:
  219. SET_PLL(PLL0, PD, PLL_PD_OFF);
  220. SET_PLL(PLL0, DACPD, freq->dacpd);
  221. SET_PLL(PLL0, DSMPD, freq->dsmpd);
  222. SET_PLL(PLL0, PREDIV, freq->prediv);
  223. SET_PLL(PLL0, FBDIV, freq->fbdiv);
  224. SET_PLL(PLL0, POSTDIV1, freq->postdiv1 >> 1);
  225. SET_PLL(PLL0, PD, PLL_PD_ON);
  226. break;
  227. case PLL1:
  228. SET_PLL(PLL1, PD, PLL_PD_OFF);
  229. SET_PLL(PLL1, DACPD, freq->dacpd);
  230. SET_PLL(PLL1, DSMPD, freq->dsmpd);
  231. SET_PLL(PLL1, PREDIV, freq->prediv);
  232. SET_PLL(PLL1, FBDIV, freq->fbdiv);
  233. SET_PLL(PLL1, POSTDIV1, freq->postdiv1 >> 1);
  234. SET_PLL(PLL1, PD, PLL_PD_ON);
  235. break;
  236. case PLL2:
  237. SET_PLL(PLL2, PD, PLL_PD_OFF);
  238. SET_PLL(PLL2, DACPD, freq->dacpd);
  239. SET_PLL(PLL2, DSMPD, freq->dsmpd);
  240. SET_PLL(PLL2, PREDIV, freq->prediv);
  241. SET_PLL(PLL2, FBDIV, freq->fbdiv);
  242. SET_PLL(PLL2, POSTDIV1, freq->postdiv1 >> 1);
  243. SET_PLL(PLL2, PD, PLL_PD_ON);
  244. break;
  245. default:
  246. debug("Unsupported pll type %d.\n", pll);
  247. break;
  248. }
  249. }
  250. static u64 pll_get_rate(enum starfive_pll_type pll,
  251. struct starfive_pll_freq *conf)
  252. {
  253. u32 dacpd, dsmpd;
  254. u32 prediv, fbdiv, postdiv1, frac;
  255. u64 refclk = 24000000;
  256. u64 freq = 0;
  257. u64 deffreq;
  258. switch (pll) {
  259. case PLL0:
  260. dacpd = GET_PLL(PLL0, DACPD);
  261. dsmpd = GET_PLL(PLL0, DSMPD);
  262. prediv = GET_PLL(PLL0, PREDIV);
  263. fbdiv = GET_PLL(PLL0, FBDIV);
  264. postdiv1 = 1 << GET_PLL(PLL0, POSTDIV1);
  265. frac = GET_PLL(PLL0, FRAC);
  266. deffreq = 1000000000;
  267. break;
  268. case PLL1:
  269. dacpd = GET_PLL(PLL1, DACPD);
  270. dsmpd = GET_PLL(PLL1, DSMPD);
  271. prediv = GET_PLL(PLL1, PREDIV);
  272. fbdiv = GET_PLL(PLL1, FBDIV);
  273. postdiv1 = 1 << GET_PLL(PLL1, POSTDIV1);
  274. frac = GET_PLL(PLL1, FRAC);
  275. deffreq = 1066000000;
  276. break;
  277. case PLL2:
  278. dacpd = GET_PLL(PLL2, DACPD);
  279. dsmpd = GET_PLL(PLL2, DSMPD);
  280. prediv = GET_PLL(PLL2, PREDIV);
  281. fbdiv = GET_PLL(PLL2, FBDIV);
  282. postdiv1 = 1 << GET_PLL(PLL2, POSTDIV1);
  283. frac = GET_PLL(PLL2, FRAC);
  284. deffreq = 1188000000;
  285. break;
  286. default:
  287. debug("Unsupported pll type %d.\n", pll);
  288. return 0;
  289. }
  290. if (dacpd == 1 && dsmpd == 1)
  291. freq = (refclk * fbdiv) / (prediv * postdiv1);
  292. else if ((dacpd == 0 && dsmpd == 0))
  293. freq = deffreq;
  294. else {
  295. debug("Unkwnon pll mode.\n");
  296. return -EINVAL;
  297. }
  298. if (conf) {
  299. conf->dacpd = dacpd;
  300. conf->dsmpd = dsmpd;
  301. conf->fbdiv = fbdiv;
  302. conf->prediv = prediv;
  303. conf->frac = frac;
  304. conf->postdiv1 = postdiv1;
  305. conf->freq = freq;
  306. }
  307. return freq;
  308. }
  309. u64 starfive_jh7110_pll_get_rate(enum starfive_pll_type pll,
  310. struct starfive_pll_freq *conf)
  311. {
  312. return pll_get_rate(pll, conf);
  313. }
  314. int starfive_jh7110_pll_set_rate(enum starfive_pll_type pll, u64 rate)
  315. {
  316. struct starfive_pll_freq *conf;
  317. struct starfive_pll_freq *freq;
  318. int i;
  319. int num;
  320. switch (pll) {
  321. case PLL0:
  322. conf = jh7110_pll0_freq;
  323. num = ARRAY_SIZE(jh7110_pll0_freq);
  324. break;
  325. case PLL1:
  326. conf = jh7110_pll1_freq;
  327. num = ARRAY_SIZE(jh7110_pll1_freq);
  328. break;
  329. case PLL2:
  330. conf = jh7110_pll2_freq;
  331. num = ARRAY_SIZE(jh7110_pll2_freq);
  332. break;
  333. default:
  334. debug("Unsupported pll type %d.\n", pll);
  335. return 0;
  336. }
  337. for (i = 0; i < num; i++) {
  338. if (conf[i].freq == rate) {
  339. freq = &conf[i];
  340. break;
  341. }
  342. }
  343. if (i < num)
  344. pll_set_rate(pll, freq);
  345. else
  346. debug("Unsupported freq %lld.\n", rate);
  347. return 0;
  348. }