fsl_corenet2_serdes.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * Copyright 2012 Freescale Semiconductor, Inc.
  3. *
  4. * See file CREDITS for list of people who contributed to this
  5. * project.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20. * MA 02111-1307 USA
  21. */
  22. #include <common.h>
  23. #include <asm/fsl_serdes.h>
  24. #include <asm/immap_85xx.h>
  25. #include <asm/io.h>
  26. #include <asm/processor.h>
  27. #include <asm/fsl_law.h>
  28. #include <asm/errno.h>
  29. #include "fsl_corenet2_serdes.h"
  30. static u64 serdes1_prtcl_map;
  31. static u64 serdes2_prtcl_map;
  32. #ifdef CONFIG_SYS_FSL_SRDS_3
  33. static u64 serdes3_prtcl_map;
  34. #endif
  35. #ifdef CONFIG_SYS_FSL_SRDS_4
  36. static u64 serdes4_prtcl_map;
  37. #endif
  38. #ifdef DEBUG
  39. static const char *serdes_prtcl_str[] = {
  40. [NONE] = "NA",
  41. [PCIE1] = "PCIE1",
  42. [PCIE2] = "PCIE2",
  43. [PCIE3] = "PCIE3",
  44. [PCIE4] = "PCIE4",
  45. [SATA1] = "SATA1",
  46. [SATA2] = "SATA2",
  47. [SRIO1] = "SRIO1",
  48. [SRIO2] = "SRIO2",
  49. [SGMII_FM1_DTSEC1] = "SGMII_FM1_DTSEC1",
  50. [SGMII_FM1_DTSEC2] = "SGMII_FM1_DTSEC2",
  51. [SGMII_FM1_DTSEC3] = "SGMII_FM1_DTSEC3",
  52. [SGMII_FM1_DTSEC4] = "SGMII_FM1_DTSEC4",
  53. [SGMII_FM1_DTSEC5] = "SGMII_FM1_DTSEC5",
  54. [SGMII_FM1_DTSEC6] = "SGMII_FM1_DTSEC6",
  55. [SGMII_FM2_DTSEC1] = "SGMII_FM2_DTSEC1",
  56. [SGMII_FM2_DTSEC2] = "SGMII_FM2_DTSEC2",
  57. [SGMII_FM2_DTSEC3] = "SGMII_FM2_DTSEC3",
  58. [SGMII_FM2_DTSEC4] = "SGMII_FM2_DTSEC4",
  59. [XAUI_FM1] = "XAUI_FM1",
  60. [XAUI_FM2] = "XAUI_FM2",
  61. [AURORA] = "DEBUG",
  62. [CPRI1] = "CPRI1",
  63. [CPRI2] = "CPRI2",
  64. [CPRI3] = "CPRI3",
  65. [CPRI4] = "CPRI4",
  66. [CPRI5] = "CPRI5",
  67. [CPRI6] = "CPRI6",
  68. [CPRI7] = "CPRI7",
  69. [CPRI8] = "CPRI8",
  70. [XAUI_FM1_MAC9] = "XAUI_FM1_MAC9",
  71. [XAUI_FM1_MAC10] = "XAUI_FM1_MAC10",
  72. [XAUI_FM2_MAC9] = "XAUI_FM2_MAC9",
  73. [XAUI_FM2_MAC10] = "XAUI_FM2_MAC10",
  74. [HIGIG_FM1_MAC9] = "HiGig_FM1_MAC9",
  75. [HIGIG_FM1_MAC10] = "HiGig_FM1_MAC10",
  76. [HIGIG_FM2_MAC9] = "HiGig_FM2_MAC9",
  77. [HIGIG_FM2_MAC10] = "HiGig_FM2_MAC10",
  78. [QSGMII_FM1_A] = "QSGMII_FM1_A",
  79. [QSGMII_FM1_B] = "QSGMII_FM1_B",
  80. [QSGMII_FM2_A] = "QSGMII_FM2_A",
  81. [QSGMII_FM2_B] = "QSGMII_FM2_B",
  82. [XFI_FM1_MAC9] = "XFI_FM1_MAC9",
  83. [XFI_FM1_MAC10] = "XFI_FM1_MAC10",
  84. [XFI_FM2_MAC9] = "XFI_FM2_MAC9",
  85. [XFI_FM2_MAC10] = "XFI_FM2_MAC10",
  86. [INTERLAKEN] = "INTERLAKEN",
  87. };
  88. #endif
  89. int is_serdes_configured(enum srds_prtcl device)
  90. {
  91. u64 ret = 0;
  92. ret |= (1ULL << device) & serdes1_prtcl_map;
  93. ret |= (1ULL << device) & serdes2_prtcl_map;
  94. #ifdef CONFIG_SYS_FSL_SRDS_3
  95. ret |= (1ULL << device) & serdes3_prtcl_map;
  96. #endif
  97. #ifdef CONFIG_SYS_FSL_SRDS_4
  98. ret |= (1ULL << device) & serdes4_prtcl_map;
  99. #endif
  100. return !!ret;
  101. }
  102. int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
  103. {
  104. const ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
  105. u32 cfg = in_be32(&gur->rcwsr[4]);
  106. int i;
  107. switch (sd) {
  108. case FSL_SRDS_1:
  109. cfg &= FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
  110. cfg >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
  111. break;
  112. case FSL_SRDS_2:
  113. cfg &= FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
  114. cfg >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
  115. break;
  116. #ifdef CONFIG_SYS_FSL_SRDS_3
  117. case FSL_SRDS_3:
  118. cfg &= FSL_CORENET2_RCWSR4_SRDS3_PRTCL;
  119. cfg >>= FSL_CORENET2_RCWSR4_SRDS3_PRTCL_SHIFT;
  120. break;
  121. #endif
  122. #ifdef CONFIG_SYS_FSL_SRDS_4
  123. case FSL_SRDS_4:
  124. cfg &= FSL_CORENET2_RCWSR4_SRDS4_PRTCL;
  125. cfg >>= FSL_CORENET2_RCWSR4_SRDS4_PRTCL_SHIFT;
  126. break;
  127. #endif
  128. default:
  129. printf("invalid SerDes%d\n", sd);
  130. break;
  131. }
  132. /* Is serdes enabled at all? */
  133. if (unlikely(cfg == 0))
  134. return -ENODEV;
  135. for (i = 0; i < SRDS_MAX_LANES; i++) {
  136. if (serdes_get_prtcl(sd, cfg, i) == device)
  137. return i;
  138. }
  139. return -ENODEV;
  140. }
  141. u64 serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift)
  142. {
  143. ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
  144. u64 serdes_prtcl_map = 0;
  145. u32 cfg;
  146. int lane;
  147. cfg = in_be32(&gur->rcwsr[4]) & sd_prctl_mask;
  148. /* Is serdes enabled at all? */
  149. if (!cfg) {
  150. printf("SERDES%d is not enabled\n", sd + 1);
  151. return 0;
  152. }
  153. cfg >>= sd_prctl_shift;
  154. printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
  155. if (!is_serdes_prtcl_valid(sd, cfg))
  156. printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
  157. for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
  158. enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
  159. serdes_prtcl_map |= (1ULL << lane_prtcl);
  160. }
  161. return serdes_prtcl_map;
  162. }
  163. void fsl_serdes_init(void)
  164. {
  165. serdes1_prtcl_map = serdes_init(FSL_SRDS_1,
  166. CONFIG_SYS_FSL_CORENET_SERDES_ADDR,
  167. FSL_CORENET2_RCWSR4_SRDS1_PRTCL,
  168. FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT);
  169. serdes2_prtcl_map = serdes_init(FSL_SRDS_2,
  170. CONFIG_SYS_FSL_CORENET_SERDES_ADDR + FSL_SRDS_2 * 0x1000,
  171. FSL_CORENET2_RCWSR4_SRDS2_PRTCL,
  172. FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT);
  173. #ifdef CONFIG_SYS_FSL_SRDS_3
  174. serdes3_prtcl_map = serdes_init(FSL_SRDS_3,
  175. CONFIG_SYS_FSL_CORENET_SERDES_ADDR + FSL_SRDS_3 * 0x1000,
  176. FSL_CORENET2_RCWSR4_SRDS3_PRTCL,
  177. FSL_CORENET2_RCWSR4_SRDS3_PRTCL_SHIFT);
  178. #endif
  179. #ifdef CONFIG_SYS_FSL_SRDS_4
  180. serdes4_prtcl_map = serdes_init(FSL_SRDS_4,
  181. CONFIG_SYS_FSL_CORENET_SERDES_ADDR + FSL_SRDS_4 * 0x1000,
  182. FSL_CORENET2_RCWSR4_SRDS4_PRTCL,
  183. FSL_CORENET2_RCWSR4_SRDS4_PRTCL_SHIFT);
  184. #endif
  185. }