1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2018 NXP 4 * 5 */ 6 7 #include <common.h> 8 #include <command.h> 9 #include <netdev.h> 10 #include <malloc.h> 11 #include <fsl_mdio.h> 12 #include <miiphy.h> 13 #include <phy.h> 14 #include <fm_eth.h> 15 #include <asm/io.h> 16 #include <exports.h> 17 #include <asm/arch/fsl_serdes.h> 18 #include <fsl-mc/fsl_mc.h> 19 #include <fsl-mc/ldpaa_wriop.h> 20 21 DECLARE_GLOBAL_DATA_PTR; 22 23 static bool get_inphi_phy_id(struct mii_dev *bus, int addr, int devad) 24 { 25 int phy_reg; 26 u32 phy_id; 27 28 phy_reg = bus->read(bus, addr, devad, MII_PHYSID1); 29 phy_id = (phy_reg & 0xffff) << 16; 30 31 phy_reg = bus->read(bus, addr, devad, MII_PHYSID2); 32 phy_id |= (phy_reg & 0xffff); 33 34 if (phy_id == PHY_UID_IN112525_S03) 35 return true; 36 else 37 return false; 38 } 39 40 int board_eth_init(bd_t *bis) 41 { 42 #if defined(CONFIG_FSL_MC_ENET) 43 struct memac_mdio_info mdio_info; 44 struct memac_mdio_controller *reg; 45 int i, interface; 46 struct mii_dev *dev; 47 struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 48 u32 srds_s1; 49 50 srds_s1 = in_le32(&gur->rcwsr[28]) & 51 FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK; 52 srds_s1 >>= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT; 53 54 reg = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO1; 55 mdio_info.regs = reg; 56 mdio_info.name = DEFAULT_WRIOP_MDIO1_NAME; 57 58 /* Register the EMI 1 */ 59 fm_memac_mdio_init(bis, &mdio_info); 60 61 reg = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO2; 62 mdio_info.regs = reg; 63 mdio_info.name = DEFAULT_WRIOP_MDIO2_NAME; 64 65 /* Register the EMI 2 */ 66 fm_memac_mdio_init(bis, &mdio_info); 67 68 dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME); 69 switch (srds_s1) { 70 case 19: 71 wriop_set_phy_address(WRIOP1_DPMAC2, 0, 72 CORTINA_PHY_ADDR1); 73 wriop_set_phy_address(WRIOP1_DPMAC3, 0, 74 AQR107_PHY_ADDR1); 75 wriop_set_phy_address(WRIOP1_DPMAC4, 0, 76 AQR107_PHY_ADDR2); 77 if (get_inphi_phy_id(dev, INPHI_PHY_ADDR1, MDIO_MMD_VEND1)) { 78 wriop_set_phy_address(WRIOP1_DPMAC5, 0, 79 INPHI_PHY_ADDR1); 80 wriop_set_phy_address(WRIOP1_DPMAC6, 0, 81 INPHI_PHY_ADDR1); 82 } 83 wriop_set_phy_address(WRIOP1_DPMAC17, 0, 84 RGMII_PHY_ADDR1); 85 wriop_set_phy_address(WRIOP1_DPMAC18, 0, 86 RGMII_PHY_ADDR2); 87 break; 88 89 case 18: 90 wriop_set_phy_address(WRIOP1_DPMAC7, 0, 91 CORTINA_PHY_ADDR1); 92 wriop_set_phy_address(WRIOP1_DPMAC8, 0, 93 CORTINA_PHY_ADDR1); 94 wriop_set_phy_address(WRIOP1_DPMAC9, 0, 95 CORTINA_PHY_ADDR1); 96 wriop_set_phy_address(WRIOP1_DPMAC10, 0, 97 CORTINA_PHY_ADDR1); 98 wriop_set_phy_address(WRIOP1_DPMAC3, 0, 99 AQR107_PHY_ADDR1); 100 wriop_set_phy_address(WRIOP1_DPMAC4, 0, 101 AQR107_PHY_ADDR2); 102 if (get_inphi_phy_id(dev, INPHI_PHY_ADDR1, MDIO_MMD_VEND1)) { 103 wriop_set_phy_address(WRIOP1_DPMAC5, 0, 104 INPHI_PHY_ADDR1); 105 wriop_set_phy_address(WRIOP1_DPMAC6, 0, 106 INPHI_PHY_ADDR1); 107 } 108 wriop_set_phy_address(WRIOP1_DPMAC17, 0, 109 RGMII_PHY_ADDR1); 110 wriop_set_phy_address(WRIOP1_DPMAC18, 0, 111 RGMII_PHY_ADDR2); 112 break; 113 114 default: 115 printf("SerDes1 protocol 0x%x is not supported on LX2160ARDB\n", 116 srds_s1); 117 goto next; 118 } 119 120 for (i = WRIOP1_DPMAC2; i <= WRIOP1_DPMAC10; i++) { 121 interface = wriop_get_enet_if(i); 122 switch (interface) { 123 case PHY_INTERFACE_MODE_XGMII: 124 dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME); 125 wriop_set_mdio(i, dev); 126 break; 127 case PHY_INTERFACE_MODE_25G_AUI: 128 dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME); 129 wriop_set_mdio(i, dev); 130 break; 131 case PHY_INTERFACE_MODE_XLAUI: 132 dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME); 133 wriop_set_mdio(i, dev); 134 break; 135 default: 136 break; 137 } 138 } 139 for (i = WRIOP1_DPMAC17; i <= WRIOP1_DPMAC18; i++) { 140 interface = wriop_get_enet_if(i); 141 switch (interface) { 142 case PHY_INTERFACE_MODE_RGMII: 143 case PHY_INTERFACE_MODE_RGMII_ID: 144 dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME); 145 wriop_set_mdio(i, dev); 146 break; 147 default: 148 break; 149 } 150 } 151 152 next: 153 cpu_eth_init(bis); 154 #endif /* CONFIG_FSL_MC_ENET */ 155 156 #ifdef CONFIG_PHY_AQUANTIA 157 /* 158 * Export functions to be used by AQ firmware 159 * upload application 160 */ 161 gd->jt->strcpy = strcpy; 162 gd->jt->mdelay = mdelay; 163 gd->jt->mdio_get_current_dev = mdio_get_current_dev; 164 gd->jt->phy_find_by_mask = phy_find_by_mask; 165 gd->jt->mdio_phydev_for_ethname = mdio_phydev_for_ethname; 166 gd->jt->miiphy_set_current_dev = miiphy_set_current_dev; 167 #endif 168 return pci_eth_init(bis); 169 } 170 171 #if defined(CONFIG_RESET_PHY_R) 172 void reset_phy(void) 173 { 174 #if defined(CONFIG_FSL_MC_ENET) 175 mc_env_boot(); 176 #endif 177 } 178 #endif /* CONFIG_RESET_PHY_R */ 179 180 int fdt_fixup_board_phy(void *fdt) 181 { 182 int mdio_offset; 183 int ret; 184 struct mii_dev *dev; 185 186 ret = 0; 187 188 dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME); 189 if (!get_inphi_phy_id(dev, INPHI_PHY_ADDR1, MDIO_MMD_VEND1)) { 190 mdio_offset = fdt_path_offset(fdt, "/soc/mdio@0x8B97000"); 191 192 if (mdio_offset < 0) 193 mdio_offset = fdt_path_offset(fdt, "/mdio@0x8B97000"); 194 195 if (mdio_offset < 0) { 196 printf("mdio@0x8B9700 node not found in dts\n"); 197 return mdio_offset; 198 } 199 200 ret = fdt_setprop_string(fdt, mdio_offset, "status", 201 "disabled"); 202 if (ret) { 203 printf("Could not set disable mdio@0x8B97000 %s\n", 204 fdt_strerror(ret)); 205 return ret; 206 } 207 } 208 209 return ret; 210 } 211