1 #include <common.h> 2 #include <dm.h> 3 #include <miiphy.h> 4 #include <asm-generic/gpio.h> 5 6 #include "ihs_phys.h" 7 #include "dt_helpers.h" 8 9 enum { 10 PORTTYPE_MAIN_CAT, 11 PORTTYPE_TOP_CAT, 12 PORTTYPE_16C_16F, 13 PORTTYPE_UNKNOWN 14 }; 15 16 static struct porttype { 17 bool phy_invert_in_pol; 18 bool phy_invert_out_pol; 19 } porttypes[] = { 20 { true, false }, 21 { false, true }, 22 { false, false }, 23 }; 24 25 static void ihs_phy_config(struct phy_device *phydev, bool qinpn, bool qoutpn) 26 { 27 u16 reg; 28 29 phy_config(phydev); 30 31 /* enable QSGMII autonegotiation with flow control */ 32 phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0004); 33 reg = phy_read(phydev, MDIO_DEVAD_NONE, 16); 34 reg |= (3 << 6); 35 phy_write(phydev, MDIO_DEVAD_NONE, 16, reg); 36 37 /* 38 * invert QSGMII Q_INP/N and Q_OUTP/N if required 39 * and perform global reset 40 */ 41 reg = phy_read(phydev, MDIO_DEVAD_NONE, 26); 42 if (qinpn) 43 reg |= (1 << 13); 44 if (qoutpn) 45 reg |= (1 << 12); 46 reg |= (1 << 15); 47 phy_write(phydev, MDIO_DEVAD_NONE, 26, reg); 48 49 /* advertise 1000BASE-T full-duplex only */ 50 phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0000); 51 reg = phy_read(phydev, MDIO_DEVAD_NONE, 4); 52 reg &= ~0x1e0; 53 phy_write(phydev, MDIO_DEVAD_NONE, 4, reg); 54 reg = phy_read(phydev, MDIO_DEVAD_NONE, 9); 55 reg = (reg & ~0x300) | 0x200; 56 phy_write(phydev, MDIO_DEVAD_NONE, 9, reg); 57 58 /* copper power up */ 59 reg = phy_read(phydev, MDIO_DEVAD_NONE, 16); 60 reg &= ~0x0004; 61 phy_write(phydev, MDIO_DEVAD_NONE, 16, reg); 62 } 63 64 uint calculate_octo_phy_mask(void) 65 { 66 uint k; 67 uint octo_phy_mask = 0; 68 struct gpio_desc gpio = {}; 69 char gpio_name[64]; 70 static const char * const dev_name[] = {"pca9698@23", "pca9698@21", 71 "pca9698@24", "pca9698@25", 72 "pca9698@26"}; 73 74 /* mark all octo phys that should be present */ 75 for (k = 0; k < 5; ++k) { 76 snprintf(gpio_name, 64, "cat-gpio-%u", k); 77 78 if (request_gpio_by_name(&gpio, dev_name[k], 0x20, gpio_name)) 79 continue; 80 81 /* check CAT flag */ 82 if (dm_gpio_get_value(&gpio)) 83 octo_phy_mask |= (1 << (k * 2)); 84 else 85 /* If CAT == 0, there's no second octo phy -> skip */ 86 continue; 87 88 snprintf(gpio_name, 64, "second-octo-gpio-%u", k); 89 90 if (request_gpio_by_name(&gpio, dev_name[k], 0x27, gpio_name)) { 91 /* default: second octo phy is present */ 92 octo_phy_mask |= (1 << (k * 2 + 1)); 93 continue; 94 } 95 96 if (dm_gpio_get_value(&gpio) == 0) 97 octo_phy_mask |= (1 << (k * 2 + 1)); 98 } 99 100 return octo_phy_mask; 101 } 102 103 int register_miiphy_bus(uint k, struct mii_dev **bus) 104 { 105 int retval; 106 struct mii_dev *mdiodev = mdio_alloc(); 107 char *name = bb_miiphy_buses[k].name; 108 109 if (!mdiodev) 110 return -ENOMEM; 111 strncpy(mdiodev->name, 112 name, 113 MDIO_NAME_LEN); 114 mdiodev->read = bb_miiphy_read; 115 mdiodev->write = bb_miiphy_write; 116 117 retval = mdio_register(mdiodev); 118 if (retval < 0) 119 return retval; 120 *bus = miiphy_get_dev_by_name(name); 121 122 return 0; 123 } 124 125 struct porttype *get_porttype(uint octo_phy_mask, uint k) 126 { 127 uint octo_index = k * 4; 128 129 if (!k) { 130 if (octo_phy_mask & 0x01) 131 return &porttypes[PORTTYPE_MAIN_CAT]; 132 else if (!(octo_phy_mask & 0x03)) 133 return &porttypes[PORTTYPE_16C_16F]; 134 } else { 135 if (octo_phy_mask & (1 << octo_index)) 136 return &porttypes[PORTTYPE_TOP_CAT]; 137 } 138 139 return NULL; 140 } 141 142 int init_single_phy(struct porttype *porttype, struct mii_dev *bus, 143 uint bus_idx, uint m, uint phy_idx) 144 { 145 struct phy_device *phydev = phy_find_by_mask( 146 bus, 1 << (m * 8 + phy_idx), 147 PHY_INTERFACE_MODE_MII); 148 149 printf(" %u", bus_idx * 32 + m * 8 + phy_idx); 150 151 if (!phydev) 152 puts("!"); 153 else 154 ihs_phy_config(phydev, porttype->phy_invert_in_pol, 155 porttype->phy_invert_out_pol); 156 157 return 0; 158 } 159 160 int init_octo_phys(uint octo_phy_mask) 161 { 162 uint bus_idx; 163 164 /* there are up to four octo-phys on each mdio bus */ 165 for (bus_idx = 0; bus_idx < bb_miiphy_buses_num; ++bus_idx) { 166 uint m; 167 uint octo_index = bus_idx * 4; 168 struct mii_dev *bus = NULL; 169 struct porttype *porttype = NULL; 170 int ret; 171 172 porttype = get_porttype(octo_phy_mask, bus_idx); 173 174 if (!porttype) 175 continue; 176 177 for (m = 0; m < 4; ++m) { 178 uint phy_idx; 179 180 /** 181 * Register a bus device if there is at least one phy 182 * on the current bus 183 */ 184 if (!m && octo_phy_mask & (0xf << octo_index)) { 185 ret = register_miiphy_bus(bus_idx, &bus); 186 if (ret) 187 return ret; 188 } 189 190 if (!(octo_phy_mask & BIT(octo_index + m))) 191 continue; 192 193 for (phy_idx = 0; phy_idx < 8; ++phy_idx) 194 init_single_phy(porttype, bus, bus_idx, m, 195 phy_idx); 196 } 197 } 198 199 return 0; 200 } 201 202 /* 203 * MII GPIO bitbang implementation 204 * MDC MDIO bus 205 * 13 14 PHY1-4 206 * 25 45 PHY5-8 207 * 46 24 PHY9-10 208 */ 209 210 struct gpio_mii { 211 int index; 212 struct gpio_desc mdc_gpio; 213 struct gpio_desc mdio_gpio; 214 int mdc_num; 215 int mdio_num; 216 int mdio_value; 217 } gpio_mii_set[] = { 218 { 0, {}, {}, 13, 14, 1 }, 219 { 1, {}, {}, 25, 45, 1 }, 220 { 2, {}, {}, 46, 24, 1 }, 221 }; 222 223 static int mii_mdio_init(struct bb_miiphy_bus *bus) 224 { 225 struct gpio_mii *gpio_mii = bus->priv; 226 char name[32] = {}; 227 struct udevice *gpio_dev1 = NULL; 228 struct udevice *gpio_dev2 = NULL; 229 230 if (uclass_get_device_by_name(UCLASS_GPIO, "gpio@18100", &gpio_dev1) || 231 uclass_get_device_by_name(UCLASS_GPIO, "gpio@18140", &gpio_dev2)) { 232 printf("Could not get GPIO device.\n"); 233 return 1; 234 } 235 236 if (gpio_mii->mdc_num > 31) { 237 gpio_mii->mdc_gpio.dev = gpio_dev2; 238 gpio_mii->mdc_gpio.offset = gpio_mii->mdc_num - 32; 239 } else { 240 gpio_mii->mdc_gpio.dev = gpio_dev1; 241 gpio_mii->mdc_gpio.offset = gpio_mii->mdc_num; 242 } 243 gpio_mii->mdc_gpio.flags = 0; 244 snprintf(name, 32, "bb_miiphy_bus-%d-mdc", gpio_mii->index); 245 dm_gpio_request(&gpio_mii->mdc_gpio, name); 246 247 if (gpio_mii->mdio_num > 31) { 248 gpio_mii->mdio_gpio.dev = gpio_dev2; 249 gpio_mii->mdio_gpio.offset = gpio_mii->mdio_num - 32; 250 } else { 251 gpio_mii->mdio_gpio.dev = gpio_dev1; 252 gpio_mii->mdio_gpio.offset = gpio_mii->mdio_num; 253 } 254 gpio_mii->mdio_gpio.flags = 0; 255 snprintf(name, 32, "bb_miiphy_bus-%d-mdio", gpio_mii->index); 256 dm_gpio_request(&gpio_mii->mdio_gpio, name); 257 258 dm_gpio_set_dir_flags(&gpio_mii->mdc_gpio, GPIOD_IS_OUT); 259 dm_gpio_set_value(&gpio_mii->mdc_gpio, 1); 260 261 return 0; 262 } 263 264 static int mii_mdio_active(struct bb_miiphy_bus *bus) 265 { 266 struct gpio_mii *gpio_mii = bus->priv; 267 268 dm_gpio_set_value(&gpio_mii->mdc_gpio, gpio_mii->mdio_value); 269 270 return 0; 271 } 272 273 static int mii_mdio_tristate(struct bb_miiphy_bus *bus) 274 { 275 struct gpio_mii *gpio_mii = bus->priv; 276 277 dm_gpio_set_dir_flags(&gpio_mii->mdio_gpio, GPIOD_IS_IN); 278 279 return 0; 280 } 281 282 static int mii_set_mdio(struct bb_miiphy_bus *bus, int v) 283 { 284 struct gpio_mii *gpio_mii = bus->priv; 285 286 dm_gpio_set_dir_flags(&gpio_mii->mdio_gpio, GPIOD_IS_OUT); 287 dm_gpio_set_value(&gpio_mii->mdio_gpio, v); 288 gpio_mii->mdio_value = v; 289 290 return 0; 291 } 292 293 static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v) 294 { 295 struct gpio_mii *gpio_mii = bus->priv; 296 297 dm_gpio_set_dir_flags(&gpio_mii->mdio_gpio, GPIOD_IS_IN); 298 *v = (dm_gpio_get_value(&gpio_mii->mdio_gpio)); 299 300 return 0; 301 } 302 303 static int mii_set_mdc(struct bb_miiphy_bus *bus, int v) 304 { 305 struct gpio_mii *gpio_mii = bus->priv; 306 307 dm_gpio_set_value(&gpio_mii->mdc_gpio, v); 308 309 return 0; 310 } 311 312 static int mii_delay(struct bb_miiphy_bus *bus) 313 { 314 udelay(1); 315 316 return 0; 317 } 318 319 struct bb_miiphy_bus bb_miiphy_buses[] = { 320 { 321 .name = "ihs0", 322 .init = mii_mdio_init, 323 .mdio_active = mii_mdio_active, 324 .mdio_tristate = mii_mdio_tristate, 325 .set_mdio = mii_set_mdio, 326 .get_mdio = mii_get_mdio, 327 .set_mdc = mii_set_mdc, 328 .delay = mii_delay, 329 .priv = &gpio_mii_set[0], 330 }, 331 { 332 .name = "ihs1", 333 .init = mii_mdio_init, 334 .mdio_active = mii_mdio_active, 335 .mdio_tristate = mii_mdio_tristate, 336 .set_mdio = mii_set_mdio, 337 .get_mdio = mii_get_mdio, 338 .set_mdc = mii_set_mdc, 339 .delay = mii_delay, 340 .priv = &gpio_mii_set[1], 341 }, 342 { 343 .name = "ihs2", 344 .init = mii_mdio_init, 345 .mdio_active = mii_mdio_active, 346 .mdio_tristate = mii_mdio_tristate, 347 .set_mdio = mii_set_mdio, 348 .get_mdio = mii_get_mdio, 349 .set_mdc = mii_set_mdc, 350 .delay = mii_delay, 351 .priv = &gpio_mii_set[2], 352 }, 353 }; 354 355 int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses); 356