fsl_lsch2_serdes.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2015 Freescale Semiconductor, Inc.
  4. */
  5. #include <common.h>
  6. #include <asm/io.h>
  7. #include <linux/errno.h>
  8. #include <asm/arch/fsl_serdes.h>
  9. #include <asm/arch/soc.h>
  10. #ifdef CONFIG_SYS_FSL_SRDS_1
  11. static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
  12. #endif
  13. #ifdef CONFIG_SYS_FSL_SRDS_2
  14. static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
  15. #endif
  16. int is_serdes_configured(enum srds_prtcl device)
  17. {
  18. int ret = 0;
  19. #ifdef CONFIG_SYS_FSL_SRDS_1
  20. if (!serdes1_prtcl_map[NONE])
  21. fsl_serdes_init();
  22. ret |= serdes1_prtcl_map[device];
  23. #endif
  24. #ifdef CONFIG_SYS_FSL_SRDS_2
  25. if (!serdes2_prtcl_map[NONE])
  26. fsl_serdes_init();
  27. ret |= serdes2_prtcl_map[device];
  28. #endif
  29. return !!ret;
  30. }
  31. int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
  32. {
  33. struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  34. u32 cfg = gur_in32(&gur->rcwsr[4]);
  35. int i;
  36. switch (sd) {
  37. #ifdef CONFIG_SYS_FSL_SRDS_1
  38. case FSL_SRDS_1:
  39. cfg &= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
  40. cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
  41. break;
  42. #endif
  43. #ifdef CONFIG_SYS_FSL_SRDS_2
  44. case FSL_SRDS_2:
  45. cfg &= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
  46. cfg >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
  47. break;
  48. #endif
  49. default:
  50. printf("invalid SerDes%d\n", sd);
  51. break;
  52. }
  53. /* Is serdes enabled at all? */
  54. if (unlikely(cfg == 0))
  55. return -ENODEV;
  56. for (i = 0; i < SRDS_MAX_LANES; i++) {
  57. if (serdes_get_prtcl(sd, cfg, i) == device)
  58. return i;
  59. }
  60. return -ENODEV;
  61. }
  62. int get_serdes_protocol(void)
  63. {
  64. struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  65. u32 cfg = gur_in32(&gur->rcwsr[4]) &
  66. FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
  67. cfg >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
  68. return cfg;
  69. }
  70. const char *serdes_clock_to_string(u32 clock)
  71. {
  72. switch (clock) {
  73. case SRDS_PLLCR0_RFCK_SEL_100:
  74. return "100";
  75. case SRDS_PLLCR0_RFCK_SEL_125:
  76. return "125";
  77. case SRDS_PLLCR0_RFCK_SEL_156_25:
  78. return "156.25";
  79. default:
  80. return "100";
  81. }
  82. }
  83. void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
  84. u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])
  85. {
  86. struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  87. u32 cfg;
  88. int lane;
  89. if (serdes_prtcl_map[NONE])
  90. return;
  91. memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT);
  92. cfg = gur_in32(&gur->rcwsr[4]) & sd_prctl_mask;
  93. cfg >>= sd_prctl_shift;
  94. printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
  95. if (!is_serdes_prtcl_valid(sd, cfg))
  96. printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
  97. for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
  98. enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
  99. if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
  100. debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
  101. else
  102. serdes_prtcl_map[lane_prtcl] = 1;
  103. }
  104. /* Set the first element to indicate serdes has been initialized */
  105. serdes_prtcl_map[NONE] = 1;
  106. }
  107. __weak int get_serdes_volt(void)
  108. {
  109. return -1;
  110. }
  111. __weak int set_serdes_volt(int svdd)
  112. {
  113. return -1;
  114. }
  115. int setup_serdes_volt(u32 svdd)
  116. {
  117. struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  118. struct ccsr_serdes *serdes1_base;
  119. #ifdef CONFIG_SYS_FSL_SRDS_2
  120. struct ccsr_serdes *serdes2_base;
  121. #endif
  122. u32 cfg_rcw4 = gur_in32(&gur->rcwsr[4]);
  123. u32 cfg_rcw5 = gur_in32(&gur->rcwsr[5]);
  124. u32 cfg_tmp, reg = 0;
  125. int svdd_cur, svdd_tar;
  126. int ret;
  127. int i;
  128. /* Only support switch SVDD to 900mV/1000mV */
  129. if (svdd != 900 && svdd != 1000)
  130. return -EINVAL;
  131. svdd_tar = svdd;
  132. svdd_cur = get_serdes_volt();
  133. if (svdd_cur < 0)
  134. return -EINVAL;
  135. debug("%s: current SVDD: %dmV; target SVDD: %dmV\n",
  136. __func__, svdd_cur, svdd_tar);
  137. if (svdd_cur == svdd_tar)
  138. return 0;
  139. serdes1_base = (void *)CONFIG_SYS_FSL_SERDES_ADDR;
  140. #ifdef CONFIG_SYS_FSL_SRDS_2
  141. serdes2_base = (void *)serdes1_base + 0x10000;
  142. #endif
  143. /* Put the all enabled lanes in reset */
  144. #ifdef CONFIG_SYS_FSL_SRDS_1
  145. cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
  146. cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
  147. for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
  148. reg = in_be32(&serdes1_base->lane[i].gcr0);
  149. reg &= 0xFF9FFFFF;
  150. out_be32(&serdes1_base->lane[i].gcr0, reg);
  151. }
  152. #endif
  153. #ifdef CONFIG_SYS_FSL_SRDS_2
  154. cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
  155. cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
  156. for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
  157. reg = in_be32(&serdes2_base->lane[i].gcr0);
  158. reg &= 0xFF9FFFFF;
  159. out_be32(&serdes2_base->lane[i].gcr0, reg);
  160. }
  161. #endif
  162. /* Put the all enabled PLL in reset */
  163. #ifdef CONFIG_SYS_FSL_SRDS_1
  164. cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
  165. for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
  166. reg = in_be32(&serdes1_base->bank[i].rstctl);
  167. reg &= 0xFFFFFFBF;
  168. reg |= 0x10000000;
  169. out_be32(&serdes1_base->bank[i].rstctl, reg);
  170. udelay(1);
  171. reg = in_be32(&serdes1_base->bank[i].rstctl);
  172. reg &= 0xFFFFFF1F;
  173. out_be32(&serdes1_base->bank[i].rstctl, reg);
  174. }
  175. udelay(1);
  176. #endif
  177. #ifdef CONFIG_SYS_FSL_SRDS_2
  178. cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
  179. for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
  180. reg = in_be32(&serdes2_base->bank[i].rstctl);
  181. reg &= 0xFFFFFFBF;
  182. reg |= 0x10000000;
  183. out_be32(&serdes2_base->bank[i].rstctl, reg);
  184. udelay(1);
  185. reg = in_be32(&serdes2_base->bank[i].rstctl);
  186. reg &= 0xFFFFFF1F;
  187. out_be32(&serdes2_base->bank[i].rstctl, reg);
  188. }
  189. udelay(1);
  190. #endif
  191. /* Put the Rx/Tx calibration into reset */
  192. #ifdef CONFIG_SYS_FSL_SRDS_1
  193. reg = in_be32(&serdes1_base->srdstcalcr);
  194. reg &= 0xF7FFFFFF;
  195. out_be32(&serdes1_base->srdstcalcr, reg);
  196. reg = in_be32(&serdes1_base->srdsrcalcr);
  197. reg &= 0xF7FFFFFF;
  198. out_be32(&serdes1_base->srdsrcalcr, reg);
  199. #endif
  200. #ifdef CONFIG_SYS_FSL_SRDS_2
  201. reg = in_be32(&serdes2_base->srdstcalcr);
  202. reg &= 0xF7FFFFFF;
  203. out_be32(&serdes2_base->srdstcalcr, reg);
  204. reg = in_be32(&serdes2_base->srdsrcalcr);
  205. reg &= 0xF7FFFFFF;
  206. out_be32(&serdes2_base->srdsrcalcr, reg);
  207. #endif
  208. /*
  209. * If SVDD set failed, will not return directly, so that the
  210. * serdes lanes can complete reseting.
  211. */
  212. ret = set_serdes_volt(svdd_tar);
  213. if (ret)
  214. printf("%s: Failed to set SVDD\n", __func__);
  215. /* Wait for SVDD to stabilize */
  216. udelay(100);
  217. /* For each PLL that’s not disabled via RCW */
  218. #ifdef CONFIG_SYS_FSL_SRDS_1
  219. cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
  220. for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
  221. reg = in_be32(&serdes1_base->bank[i].rstctl);
  222. reg |= 0x00000020;
  223. out_be32(&serdes1_base->bank[i].rstctl, reg);
  224. udelay(1);
  225. reg = in_be32(&serdes1_base->bank[i].rstctl);
  226. reg |= 0x00000080;
  227. out_be32(&serdes1_base->bank[i].rstctl, reg);
  228. /* Take the Rx/Tx calibration out of reset */
  229. if (!(cfg_tmp == 0x3 && i == 1)) {
  230. udelay(1);
  231. reg = in_be32(&serdes1_base->srdstcalcr);
  232. reg |= 0x08000000;
  233. out_be32(&serdes1_base->srdstcalcr, reg);
  234. reg = in_be32(&serdes1_base->srdsrcalcr);
  235. reg |= 0x08000000;
  236. out_be32(&serdes1_base->srdsrcalcr, reg);
  237. }
  238. }
  239. udelay(1);
  240. #endif
  241. #ifdef CONFIG_SYS_FSL_SRDS_2
  242. cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
  243. for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
  244. reg = in_be32(&serdes2_base->bank[i].rstctl);
  245. reg |= 0x00000020;
  246. out_be32(&serdes2_base->bank[i].rstctl, reg);
  247. udelay(1);
  248. reg = in_be32(&serdes2_base->bank[i].rstctl);
  249. reg |= 0x00000080;
  250. out_be32(&serdes2_base->bank[i].rstctl, reg);
  251. /* Take the Rx/Tx calibration out of reset */
  252. if (!(cfg_tmp == 0x3 && i == 1)) {
  253. udelay(1);
  254. reg = in_be32(&serdes2_base->srdstcalcr);
  255. reg |= 0x08000000;
  256. out_be32(&serdes2_base->srdstcalcr, reg);
  257. reg = in_be32(&serdes2_base->srdsrcalcr);
  258. reg |= 0x08000000;
  259. out_be32(&serdes2_base->srdsrcalcr, reg);
  260. }
  261. }
  262. udelay(1);
  263. #endif
  264. /* Wait for at lesat 625us to ensure the PLLs being reset are locked */
  265. udelay(800);
  266. #ifdef CONFIG_SYS_FSL_SRDS_1
  267. cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
  268. for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
  269. /* if the PLL is not locked, set RST_ERR */
  270. reg = in_be32(&serdes1_base->bank[i].pllcr0);
  271. if (!((reg >> 23) & 0x1)) {
  272. reg = in_be32(&serdes1_base->bank[i].rstctl);
  273. reg |= 0x20000000;
  274. out_be32(&serdes1_base->bank[i].rstctl, reg);
  275. } else {
  276. udelay(1);
  277. reg = in_be32(&serdes1_base->bank[i].rstctl);
  278. reg &= 0xFFFFFFEF;
  279. reg |= 0x00000040;
  280. out_be32(&serdes1_base->bank[i].rstctl, reg);
  281. udelay(1);
  282. }
  283. }
  284. #endif
  285. #ifdef CONFIG_SYS_FSL_SRDS_2
  286. cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
  287. for (i = 0; i < 2 && !(cfg_tmp & (0x1 << (1 - i))); i++) {
  288. reg = in_be32(&serdes2_base->bank[i].pllcr0);
  289. if (!((reg >> 23) & 0x1)) {
  290. reg = in_be32(&serdes2_base->bank[i].rstctl);
  291. reg |= 0x20000000;
  292. out_be32(&serdes2_base->bank[i].rstctl, reg);
  293. } else {
  294. udelay(1);
  295. reg = in_be32(&serdes2_base->bank[i].rstctl);
  296. reg &= 0xFFFFFFEF;
  297. reg |= 0x00000040;
  298. out_be32(&serdes2_base->bank[i].rstctl, reg);
  299. udelay(1);
  300. }
  301. }
  302. #endif
  303. /* Take the all enabled lanes out of reset */
  304. #ifdef CONFIG_SYS_FSL_SRDS_1
  305. cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK;
  306. cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT;
  307. for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
  308. reg = in_be32(&serdes1_base->lane[i].gcr0);
  309. reg |= 0x00600000;
  310. out_be32(&serdes1_base->lane[i].gcr0, reg);
  311. }
  312. #endif
  313. #ifdef CONFIG_SYS_FSL_SRDS_2
  314. cfg_tmp = cfg_rcw4 & FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK;
  315. cfg_tmp >>= FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT;
  316. for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
  317. reg = in_be32(&serdes2_base->lane[i].gcr0);
  318. reg |= 0x00600000;
  319. out_be32(&serdes2_base->lane[i].gcr0, reg);
  320. }
  321. #endif
  322. /* For each PLL being reset, and achieved PLL lock set RST_DONE */
  323. #ifdef CONFIG_SYS_FSL_SRDS_1
  324. cfg_tmp = (cfg_rcw5 >> 22) & 0x3;
  325. for (i = 0; i < 2; i++) {
  326. reg = in_be32(&serdes1_base->bank[i].pllcr0);
  327. if (!(cfg_tmp & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) {
  328. reg = in_be32(&serdes1_base->bank[i].rstctl);
  329. reg |= 0x40000000;
  330. out_be32(&serdes1_base->bank[i].rstctl, reg);
  331. }
  332. }
  333. #endif
  334. #ifdef CONFIG_SYS_FSL_SRDS_2
  335. cfg_tmp = (cfg_rcw5 >> 20) & 0x3;
  336. for (i = 0; i < 2; i++) {
  337. reg = in_be32(&serdes2_base->bank[i].pllcr0);
  338. if (!(cfg_tmp & (0x1 << (1 - i))) && ((reg >> 23) & 0x1)) {
  339. reg = in_be32(&serdes2_base->bank[i].rstctl);
  340. reg |= 0x40000000;
  341. out_be32(&serdes2_base->bank[i].rstctl, reg);
  342. }
  343. }
  344. #endif
  345. return ret;
  346. }
  347. void fsl_serdes_init(void)
  348. {
  349. #ifdef CONFIG_SYS_FSL_SRDS_1
  350. serdes_init(FSL_SRDS_1,
  351. CONFIG_SYS_FSL_SERDES_ADDR,
  352. FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_MASK,
  353. FSL_CHASSIS2_RCWSR4_SRDS1_PRTCL_SHIFT,
  354. serdes1_prtcl_map);
  355. #endif
  356. #ifdef CONFIG_SYS_FSL_SRDS_2
  357. serdes_init(FSL_SRDS_2,
  358. CONFIG_SYS_FSL_SERDES_ADDR,
  359. FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_MASK,
  360. FSL_CHASSIS2_RCWSR4_SRDS2_PRTCL_SHIFT,
  361. serdes2_prtcl_map);
  362. #endif
  363. }