eth_b4860qds.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2012 Freescale Semiconductor, Inc.
  4. * Author: Sandeep Kumar Singh <sandeep@freescale.com>
  5. */
  6. /* This file is based on board/freescale/corenet_ds/eth_superhydra.c */
  7. /*
  8. * This file handles the board muxing between the Fman Ethernet MACs and
  9. * the RGMII/SGMII/XGMII PHYs on a Freescale B4860 "Centaur". The SGMII
  10. * PHYs are the two on-board 1Gb ports. There are no RGMII PHY on board.
  11. * The 10Gb XGMII PHY is provided via the XAUI riser card. There is only
  12. * one Fman device on B4860. The SERDES configuration is used to determine
  13. * where the SGMII and XAUI cards exist, and also which Fman MACs are routed
  14. * to which PHYs. So for a given Fman MAC, there is one and only PHY it
  15. * connects to. MACs cannot be routed to PHYs dynamically. This configuration
  16. * is done at boot time by reading SERDES protocol from RCW.
  17. */
  18. #include <common.h>
  19. #include <netdev.h>
  20. #include <asm/fsl_serdes.h>
  21. #include <fm_eth.h>
  22. #include <fsl_mdio.h>
  23. #include <malloc.h>
  24. #include <fdt_support.h>
  25. #include <fsl_dtsec.h>
  26. #include "../common/ngpixis.h"
  27. #include "../common/fman.h"
  28. #include "../common/qixis.h"
  29. #include "b4860qds_qixis.h"
  30. #define EMI_NONE 0xFFFFFFFF
  31. #ifdef CONFIG_FMAN_ENET
  32. /*
  33. * Mapping of all 16 SERDES lanes to board slots. A value n(>0) will mean that
  34. * lane at index is mapped to slot number n. A value of '0' will mean
  35. * that the mapping must be determined dynamically, or that the lane maps to
  36. * something other than a board slot
  37. */
  38. static u8 lane_to_slot[] = {
  39. 0, 0, 0, 0,
  40. 0, 0, 0, 0,
  41. 1, 1, 1, 1,
  42. 0, 0, 0, 0
  43. };
  44. /*
  45. * This function initializes the lane_to_slot[] array. It reads RCW to check
  46. * if Serdes2{E,F,G,H} is configured as slot 2 or as SFP and initializes
  47. * lane_to_slot[] accordingly
  48. */
  49. static void initialize_lane_to_slot(void)
  50. {
  51. unsigned int serdes2_prtcl;
  52. ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
  53. serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
  54. FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
  55. serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
  56. debug("Initializing lane to slot: Serdes2 protocol: %x\n",
  57. serdes2_prtcl);
  58. switch (serdes2_prtcl) {
  59. case 0x17:
  60. case 0x18:
  61. /*
  62. * Configuration:
  63. * SERDES: 2
  64. * Lanes: A,B,C,D: SGMII
  65. * Lanes: E,F: Aur
  66. * Lanes: G,H: SRIO
  67. */
  68. case 0x91:
  69. /*
  70. * Configuration:
  71. * SERDES: 2
  72. * Lanes: A,B: SGMII
  73. * Lanes: C,D: SRIO2
  74. * Lanes: E,F,G,H: XAUI2
  75. */
  76. case 0x93:
  77. /*
  78. * Configuration:
  79. * SERDES: 2
  80. * Lanes: A,B,C,D: SGMII
  81. * Lanes: E,F,G,H: XAUI2
  82. */
  83. case 0x98:
  84. /*
  85. * Configuration:
  86. * SERDES: 2
  87. * Lanes: A,B,C,D: XAUI2
  88. * Lanes: E,F,G,H: XAUI2
  89. */
  90. case 0x9a:
  91. /*
  92. * Configuration:
  93. * SERDES: 2
  94. * Lanes: A,B: PCI
  95. * Lanes: C,D: SGMII
  96. * Lanes: E,F,G,H: XAUI2
  97. */
  98. case 0x9e:
  99. /*
  100. * Configuration:
  101. * SERDES: 2
  102. * Lanes: A,B,C,D: PCI
  103. * Lanes: E,F,G,H: XAUI2
  104. */
  105. case 0xb1:
  106. case 0xb2:
  107. case 0x8c:
  108. case 0x8d:
  109. /*
  110. * Configuration:
  111. * SERDES: 2
  112. * Lanes: A,B,C,D: PCI
  113. * Lanes: E,F: SGMII 3&4
  114. * Lanes: G,H: XFI
  115. */
  116. case 0xc2:
  117. /*
  118. * Configuration:
  119. * SERDES: 2
  120. * Lanes: A,B: SGMII
  121. * Lanes: C,D: SRIO2
  122. * Lanes: E,F,G,H: XAUI2
  123. */
  124. lane_to_slot[12] = 2;
  125. lane_to_slot[13] = lane_to_slot[12];
  126. lane_to_slot[14] = lane_to_slot[12];
  127. lane_to_slot[15] = lane_to_slot[12];
  128. break;
  129. default:
  130. printf("Fman: Unsupported SerDes2 Protocol 0x%02x\n",
  131. serdes2_prtcl);
  132. break;
  133. }
  134. return;
  135. }
  136. #endif /* #ifdef CONFIG_FMAN_ENET */
  137. int board_eth_init(bd_t *bis)
  138. {
  139. #ifdef CONFIG_FMAN_ENET
  140. struct memac_mdio_info memac_mdio_info;
  141. struct memac_mdio_info tg_memac_mdio_info;
  142. unsigned int i;
  143. unsigned int serdes1_prtcl, serdes2_prtcl;
  144. int qsgmii;
  145. struct mii_dev *bus;
  146. ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
  147. serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
  148. FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
  149. if (!serdes1_prtcl) {
  150. printf("SERDES1 is not enabled\n");
  151. return 0;
  152. }
  153. serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
  154. debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
  155. serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
  156. FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
  157. if (!serdes2_prtcl) {
  158. printf("SERDES2 is not enabled\n");
  159. return 0;
  160. }
  161. serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
  162. debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
  163. printf("Initializing Fman\n");
  164. initialize_lane_to_slot();
  165. memac_mdio_info.regs =
  166. (struct memac_mdio_controller *)CONFIG_SYS_FM1_DTSEC_MDIO_ADDR;
  167. memac_mdio_info.name = DEFAULT_FM_MDIO_NAME;
  168. /* Register the real 1G MDIO bus */
  169. fm_memac_mdio_init(bis, &memac_mdio_info);
  170. tg_memac_mdio_info.regs =
  171. (struct memac_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR;
  172. tg_memac_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME;
  173. /* Register the real 10G MDIO bus */
  174. fm_memac_mdio_init(bis, &tg_memac_mdio_info);
  175. /*
  176. * Program the two on board DTSEC PHY addresses assuming that they are
  177. * all SGMII. RGMII is not supported on this board. Setting SGMII 5 and
  178. * 6 to on board SGMII phys
  179. */
  180. fm_info_set_phy_address(FM1_DTSEC5, CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR);
  181. fm_info_set_phy_address(FM1_DTSEC6, CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR);
  182. switch (serdes1_prtcl) {
  183. case 0x29:
  184. case 0x2a:
  185. /* Serdes 1: A-B SGMII, Configuring DTSEC 5 and 6 */
  186. debug("Set phy addresses for FM1_DTSEC5:%x, FM1_DTSEC6:%x\n",
  187. CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR,
  188. CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR);
  189. fm_info_set_phy_address(FM1_DTSEC5,
  190. CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR);
  191. fm_info_set_phy_address(FM1_DTSEC6,
  192. CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR);
  193. break;
  194. #ifdef CONFIG_ARCH_B4420
  195. case 0x17:
  196. case 0x18:
  197. /* Serdes 1: A-D SGMII, Configuring on board dual SGMII Phy */
  198. debug("Set phy addresses for FM1_DTSEC3:%x, FM1_DTSEC4:%x\n",
  199. CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR,
  200. CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR);
  201. /* Fixing Serdes clock by programming FPGA register */
  202. QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
  203. fm_info_set_phy_address(FM1_DTSEC3,
  204. CONFIG_SYS_FM1_ONBOARD_PHY1_ADDR);
  205. fm_info_set_phy_address(FM1_DTSEC4,
  206. CONFIG_SYS_FM1_ONBOARD_PHY2_ADDR);
  207. break;
  208. #endif
  209. default:
  210. printf("Fman: Unsupported SerDes1 Protocol 0x%02x\n",
  211. serdes1_prtcl);
  212. break;
  213. }
  214. switch (serdes2_prtcl) {
  215. case 0x17:
  216. case 0x18:
  217. debug("Set phy address on SGMII Riser for FM1_DTSEC1:%x\n",
  218. CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
  219. fm_info_set_phy_address(FM1_DTSEC1,
  220. CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
  221. fm_info_set_phy_address(FM1_DTSEC2,
  222. CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR);
  223. fm_info_set_phy_address(FM1_DTSEC3,
  224. CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR);
  225. fm_info_set_phy_address(FM1_DTSEC4,
  226. CONFIG_SYS_FM1_DTSEC4_RISER_PHY_ADDR);
  227. break;
  228. case 0x48:
  229. case 0x49:
  230. debug("Set phy address on SGMII Riser for FM1_DTSEC1:%x\n",
  231. CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
  232. fm_info_set_phy_address(FM1_DTSEC1,
  233. CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
  234. fm_info_set_phy_address(FM1_DTSEC2,
  235. CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR);
  236. fm_info_set_phy_address(FM1_DTSEC3,
  237. CONFIG_SYS_FM1_DTSEC3_RISER_PHY_ADDR);
  238. break;
  239. case 0xb1:
  240. case 0xb2:
  241. case 0x8c:
  242. case 0x8d:
  243. debug("Set phy addresses on SGMII Riser for FM1_DTSEC1:%x\n",
  244. CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
  245. fm_info_set_phy_address(FM1_DTSEC3,
  246. CONFIG_SYS_FM1_DTSEC1_RISER_PHY_ADDR);
  247. fm_info_set_phy_address(FM1_DTSEC4,
  248. CONFIG_SYS_FM1_DTSEC2_RISER_PHY_ADDR);
  249. /*
  250. * XFI does not need a PHY to work, but to make U-Boot
  251. * happy, assign a fake PHY address for a XFI port.
  252. */
  253. fm_info_set_phy_address(FM1_10GEC1, 0);
  254. fm_info_set_phy_address(FM1_10GEC2, 1);
  255. break;
  256. case 0x98:
  257. /* XAUI in Slot1 and Slot2 */
  258. debug("Set phy address of AMC2PEX-2S for FM1_10GEC1:%x\n",
  259. CONFIG_SYS_FM1_10GEC1_PHY_ADDR);
  260. fm_info_set_phy_address(FM1_10GEC1,
  261. CONFIG_SYS_FM1_10GEC1_PHY_ADDR);
  262. debug("Set phy address of AMC2PEX-2S for FM1_10GEC2:%x\n",
  263. CONFIG_SYS_FM1_10GEC2_PHY_ADDR);
  264. fm_info_set_phy_address(FM1_10GEC2,
  265. CONFIG_SYS_FM1_10GEC2_PHY_ADDR);
  266. break;
  267. case 0x9E:
  268. /* XAUI in Slot2 */
  269. debug("Sett phy address of AMC2PEX-2S for FM1_10GEC2:%x\n",
  270. CONFIG_SYS_FM1_10GEC2_PHY_ADDR);
  271. fm_info_set_phy_address(FM1_10GEC2,
  272. CONFIG_SYS_FM1_10GEC2_PHY_ADDR);
  273. break;
  274. default:
  275. printf("Fman: Unsupported SerDes2 Protocol 0x%02x\n",
  276. serdes2_prtcl);
  277. break;
  278. }
  279. /*set PHY address for QSGMII Riser Card on slot2*/
  280. bus = miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME);
  281. qsgmii = is_qsgmii_riser_card(bus, PHY_BASE_ADDR, PORT_NUM, REGNUM);
  282. if (qsgmii) {
  283. switch (serdes2_prtcl) {
  284. case 0xb2:
  285. case 0x8d:
  286. fm_info_set_phy_address(FM1_DTSEC3, PHY_BASE_ADDR);
  287. fm_info_set_phy_address(FM1_DTSEC4, PHY_BASE_ADDR + 1);
  288. break;
  289. default:
  290. break;
  291. }
  292. }
  293. for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
  294. int idx = i - FM1_DTSEC1;
  295. switch (fm_info_get_enet_if(i)) {
  296. case PHY_INTERFACE_MODE_SGMII:
  297. fm_info_set_mdio(i,
  298. miiphy_get_dev_by_name(DEFAULT_FM_MDIO_NAME));
  299. break;
  300. case PHY_INTERFACE_MODE_NONE:
  301. fm_info_set_phy_address(i, 0);
  302. break;
  303. default:
  304. printf("Fman1: DTSEC%u set to unknown interface %i\n",
  305. idx + 1, fm_info_get_enet_if(i));
  306. fm_info_set_phy_address(i, 0);
  307. break;
  308. }
  309. }
  310. for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) {
  311. int idx = i - FM1_10GEC1;
  312. switch (fm_info_get_enet_if(i)) {
  313. case PHY_INTERFACE_MODE_XGMII:
  314. fm_info_set_mdio(i,
  315. miiphy_get_dev_by_name
  316. (DEFAULT_FM_TGEC_MDIO_NAME));
  317. break;
  318. case PHY_INTERFACE_MODE_NONE:
  319. fm_info_set_phy_address(i, 0);
  320. break;
  321. default:
  322. printf("Fman1: TGEC%u set to unknown interface %i\n",
  323. idx + 1, fm_info_get_enet_if(i));
  324. fm_info_set_phy_address(i, 0);
  325. break;
  326. }
  327. }
  328. cpu_eth_init(bis);
  329. #endif
  330. return pci_eth_init(bis);
  331. }
  332. void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr,
  333. enum fm_port port, int offset)
  334. {
  335. int phy;
  336. char alias[32];
  337. struct fixed_link f_link;
  338. ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
  339. u32 prtcl2 = in_be32(&gur->rcwsr[4]) & FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
  340. prtcl2 >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
  341. if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) {
  342. phy = fm_info_get_phy_address(port);
  343. sprintf(alias, "phy_sgmii_%x", phy);
  344. fdt_set_phy_handle(fdt, compat, addr, alias);
  345. fdt_status_okay_by_alias(fdt, alias);
  346. } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_XGMII) {
  347. /* check if it's XFI interface for 10g */
  348. switch (prtcl2) {
  349. case 0x80:
  350. case 0x81:
  351. case 0x82:
  352. case 0x83:
  353. case 0x84:
  354. case 0x85:
  355. case 0x86:
  356. case 0x87:
  357. case 0x88:
  358. case 0x89:
  359. case 0x8a:
  360. case 0x8b:
  361. case 0x8c:
  362. case 0x8d:
  363. case 0x8e:
  364. case 0xb1:
  365. case 0xb2:
  366. f_link.phy_id = port;
  367. f_link.duplex = 1;
  368. f_link.link_speed = 10000;
  369. f_link.pause = 0;
  370. f_link.asym_pause = 0;
  371. fdt_delprop(fdt, offset, "phy-handle");
  372. fdt_setprop(fdt, offset, "fixed-link", &f_link,
  373. sizeof(f_link));
  374. break;
  375. case 0x98: /* XAUI interface */
  376. strcpy(alias, "phy_xaui_slot1");
  377. fdt_status_okay_by_alias(fdt, alias);
  378. strcpy(alias, "phy_xaui_slot2");
  379. fdt_status_okay_by_alias(fdt, alias);
  380. break;
  381. case 0x9e: /* XAUI interface */
  382. case 0x9a:
  383. case 0x93:
  384. case 0x91:
  385. strcpy(alias, "phy_xaui_slot1");
  386. fdt_status_okay_by_alias(fdt, alias);
  387. break;
  388. case 0x97: /* XAUI interface */
  389. case 0xc3:
  390. strcpy(alias, "phy_xaui_slot2");
  391. fdt_status_okay_by_alias(fdt, alias);
  392. break;
  393. default:
  394. break;
  395. }
  396. }
  397. }
  398. /*
  399. * Set status to disabled for unused ethernet node
  400. */
  401. void fdt_fixup_board_enet(void *fdt)
  402. {
  403. int i;
  404. char alias[32];
  405. for (i = FM1_DTSEC1; i <= FM1_10GEC2; i++) {
  406. switch (fm_info_get_enet_if(i)) {
  407. case PHY_INTERFACE_MODE_NONE:
  408. sprintf(alias, "ethernet%u", i);
  409. fdt_status_disabled_by_alias(fdt, alias);
  410. break;
  411. default:
  412. break;
  413. }
  414. }
  415. }