fsl_lsch3_serdes.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * Copyright 2014-2015 Freescale Semiconductor, Inc.
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <asm/io.h>
  8. #include <asm/errno.h>
  9. #include <asm/arch/fsl_serdes.h>
  10. #include <asm/arch/soc.h>
  11. #include <fsl-mc/ldpaa_wriop.h>
  12. #ifdef CONFIG_SYS_FSL_SRDS_1
  13. static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
  14. #endif
  15. #ifdef CONFIG_SYS_FSL_SRDS_2
  16. static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
  17. #endif
  18. #ifdef CONFIG_FSL_MC_ENET
  19. int xfi_dpmac[XFI8 + 1];
  20. int sgmii_dpmac[SGMII16 + 1];
  21. #endif
  22. int is_serdes_configured(enum srds_prtcl device)
  23. {
  24. int ret = 0;
  25. #ifdef CONFIG_SYS_FSL_SRDS_1
  26. ret |= serdes1_prtcl_map[device];
  27. #endif
  28. #ifdef CONFIG_SYS_FSL_SRDS_2
  29. ret |= serdes2_prtcl_map[device];
  30. #endif
  31. return !!ret;
  32. }
  33. int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
  34. {
  35. struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  36. u32 cfg = gur_in32(&gur->rcwsr[28]);
  37. int i;
  38. switch (sd) {
  39. #ifdef CONFIG_SYS_FSL_SRDS_1
  40. case FSL_SRDS_1:
  41. cfg &= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK;
  42. cfg >>= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
  43. break;
  44. #endif
  45. #ifdef CONFIG_SYS_FSL_SRDS_2
  46. case FSL_SRDS_2:
  47. cfg &= FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK;
  48. cfg >>= FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
  49. break;
  50. #endif
  51. default:
  52. printf("invalid SerDes%d\n", sd);
  53. break;
  54. }
  55. /* Is serdes enabled at all? */
  56. if (cfg == 0)
  57. return -ENODEV;
  58. for (i = 0; i < SRDS_MAX_LANES; i++) {
  59. if (serdes_get_prtcl(sd, cfg, i) == device)
  60. return i;
  61. }
  62. return -ENODEV;
  63. }
  64. void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
  65. u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])
  66. {
  67. struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  68. u32 cfg;
  69. int lane;
  70. memset(serdes_prtcl_map, 0, sizeof(serdes_prtcl_map));
  71. cfg = gur_in32(&gur->rcwsr[28]) & sd_prctl_mask;
  72. cfg >>= sd_prctl_shift;
  73. printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
  74. if (!is_serdes_prtcl_valid(sd, cfg))
  75. printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
  76. for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
  77. enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
  78. if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
  79. debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
  80. else {
  81. serdes_prtcl_map[lane_prtcl] = 1;
  82. #ifdef CONFIG_FSL_MC_ENET
  83. switch (lane_prtcl) {
  84. case QSGMII_A:
  85. wriop_init_dpmac(sd, 5, (int)lane_prtcl);
  86. wriop_init_dpmac(sd, 6, (int)lane_prtcl);
  87. wriop_init_dpmac(sd, 7, (int)lane_prtcl);
  88. wriop_init_dpmac(sd, 8, (int)lane_prtcl);
  89. break;
  90. case QSGMII_B:
  91. wriop_init_dpmac(sd, 1, (int)lane_prtcl);
  92. wriop_init_dpmac(sd, 2, (int)lane_prtcl);
  93. wriop_init_dpmac(sd, 3, (int)lane_prtcl);
  94. wriop_init_dpmac(sd, 4, (int)lane_prtcl);
  95. break;
  96. case QSGMII_C:
  97. wriop_init_dpmac(sd, 13, (int)lane_prtcl);
  98. wriop_init_dpmac(sd, 14, (int)lane_prtcl);
  99. wriop_init_dpmac(sd, 15, (int)lane_prtcl);
  100. wriop_init_dpmac(sd, 16, (int)lane_prtcl);
  101. break;
  102. case QSGMII_D:
  103. wriop_init_dpmac(sd, 9, (int)lane_prtcl);
  104. wriop_init_dpmac(sd, 10, (int)lane_prtcl);
  105. wriop_init_dpmac(sd, 11, (int)lane_prtcl);
  106. wriop_init_dpmac(sd, 12, (int)lane_prtcl);
  107. break;
  108. default:
  109. if (lane_prtcl >= XFI1 && lane_prtcl <= XFI8)
  110. wriop_init_dpmac(sd,
  111. xfi_dpmac[lane_prtcl],
  112. (int)lane_prtcl);
  113. if (lane_prtcl >= SGMII1 &&
  114. lane_prtcl <= SGMII16)
  115. wriop_init_dpmac(sd, sgmii_dpmac[
  116. lane_prtcl],
  117. (int)lane_prtcl);
  118. break;
  119. }
  120. #endif
  121. }
  122. }
  123. }
  124. void fsl_serdes_init(void)
  125. {
  126. #ifdef CONFIG_FSL_MC_ENET
  127. int i , j;
  128. for (i = XFI1, j = 1; i <= XFI8; i++, j++)
  129. xfi_dpmac[i] = j;
  130. for (i = SGMII1, j = 1; i <= SGMII16; i++, j++)
  131. sgmii_dpmac[i] = j;
  132. #endif
  133. #ifdef CONFIG_SYS_FSL_SRDS_1
  134. serdes_init(FSL_SRDS_1,
  135. CONFIG_SYS_FSL_LSCH3_SERDES_ADDR,
  136. FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK,
  137. FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT,
  138. serdes1_prtcl_map);
  139. #endif
  140. #ifdef CONFIG_SYS_FSL_SRDS_2
  141. serdes_init(FSL_SRDS_2,
  142. CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + FSL_SRDS_2 * 0x10000,
  143. FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK,
  144. FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT,
  145. serdes2_prtcl_map);
  146. #endif
  147. }