1 /* 2 * Xilinx xps_ll_temac ethernet driver for u-boot 3 * 4 * supports SDMA or FIFO access and MDIO bus communication 5 * 6 * Copyright (C) 2011 - 2012 Stephan Linz <linz@li-pro.net> 7 * Copyright (C) 2008 - 2011 Michal Simek <monstr@monstr.eu> 8 * Copyright (C) 2008 - 2011 PetaLogix 9 * 10 * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver 11 * Copyright (C) 2008 Nissin Systems Co.,Ltd. 12 * March 2008 created 13 * 14 * SPDX-License-Identifier: GPL-2.0+ 15 * 16 * [0]: http://www.xilinx.com/support/documentation 17 * 18 * [S]: [0]/ip_documentation/xps_ll_temac.pdf 19 * [A]: [0]/application_notes/xapp1041.pdf 20 */ 21 22 #include <config.h> 23 #include <common.h> 24 #include <net.h> 25 #include <netdev.h> 26 #include <malloc.h> 27 #include <asm/io.h> 28 #include <miiphy.h> 29 30 #include "xilinx_ll_temac.h" 31 #include "xilinx_ll_temac_fifo.h" 32 #include "xilinx_ll_temac_sdma.h" 33 #include "xilinx_ll_temac_mdio.h" 34 35 #if !defined(CONFIG_MII) 36 # error "LL_TEMAC requires MII -- missing CONFIG_MII" 37 #endif 38 39 #if !defined(CONFIG_PHYLIB) 40 # error "LL_TEMAC requires PHYLIB -- missing CONFIG_PHYLIB" 41 #endif 42 43 struct ll_temac_info { 44 int flags; 45 unsigned long base_addr; 46 unsigned long ctrl_addr; 47 char *devname; 48 unsigned int phyaddr; 49 char *mdio_busname; 50 }; 51 52 /* Ethernet interface ready status */ 53 int ll_temac_check_status(struct temac_reg *regs, u32 mask) 54 { 55 unsigned timeout = 50; /* 1usec * 50 = 50usec */ 56 57 /* 58 * Quote from LL TEMAC documentation: The bits in the RDY 59 * register are asserted when there is no access in progress. 60 * When an access is in progress, a bit corresponding to the 61 * type of access is automatically de-asserted. The bit is 62 * automatically re-asserted when the access is complete. 63 */ 64 while (timeout && (!(in_be32(®s->rdy) & mask))) { 65 timeout--; 66 udelay(1); 67 } 68 69 if (!timeout) { 70 printf("%s: Timeout on 0x%08x @%p\n", __func__, 71 mask, ®s->rdy); 72 return 1; 73 } 74 75 return 0; 76 } 77 78 /* 79 * Indirect write to ll_temac. 80 * 81 * http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf 82 * page 23, second paragraph, The use of CTL0 register or CTL1 register 83 */ 84 int ll_temac_indirect_set(struct temac_reg *regs, u16 regn, u32 reg_data) 85 { 86 out_be32(®s->lsw, (reg_data & MLSW_MASK)); 87 out_be32(®s->ctl, CTL_WEN | (regn & CTL_ADDR_MASK)); 88 89 if (ll_temac_check_status(regs, RSE_CFG_WR)) 90 return 0; 91 92 return 1; 93 } 94 95 /* 96 * Indirect read from ll_temac. 97 * 98 * http://www.xilinx.com/support/documentation/ip_documentation/xps_ll_temac.pdf 99 * page 23, second paragraph, The use of CTL0 register or CTL1 register 100 */ 101 int ll_temac_indirect_get(struct temac_reg *regs, u16 regn, u32* reg_data) 102 { 103 out_be32(®s->ctl, (regn & CTL_ADDR_MASK)); 104 105 if (ll_temac_check_status(regs, RSE_CFG_RR)) 106 return 0; 107 108 *reg_data = in_be32(®s->lsw) & MLSW_MASK; 109 return 1; 110 } 111 112 /* setting sub-controller and ll_temac to proper setting */ 113 static int ll_temac_setup_ctrl(struct eth_device *dev) 114 { 115 struct ll_temac *ll_temac = dev->priv; 116 struct temac_reg *regs = (struct temac_reg *)dev->iobase; 117 118 if (ll_temac->ctrlreset && ll_temac->ctrlreset(dev)) 119 return 0; 120 121 if (ll_temac->ctrlinit && ll_temac->ctrlinit(dev)) 122 return 0; 123 124 /* Promiscuous mode disable */ 125 if (!ll_temac_indirect_set(regs, TEMAC_AFM, 0)) 126 return 0; 127 128 /* Enable Receiver - RX bit */ 129 if (!ll_temac_indirect_set(regs, TEMAC_RCW1, RCW1_RX)) 130 return 0; 131 132 /* Enable Transmitter - TX bit */ 133 if (!ll_temac_indirect_set(regs, TEMAC_TC, TC_TX)) 134 return 0; 135 136 return 1; 137 } 138 139 /* 140 * Configure ll_temac based on negotiated speed and duplex 141 * reported by PHY handling code 142 */ 143 static int ll_temac_adjust_link(struct eth_device *dev) 144 { 145 unsigned int speed, emmc_reg; 146 struct temac_reg *regs = (struct temac_reg *)dev->iobase; 147 struct ll_temac *ll_temac = dev->priv; 148 struct phy_device *phydev = ll_temac->phydev; 149 150 if (!phydev->link) { 151 printf("%s: No link.\n", phydev->dev->name); 152 return 0; 153 } 154 155 switch (phydev->speed) { 156 case 1000: 157 speed = EMMC_LSPD_1000; 158 break; 159 case 100: 160 speed = EMMC_LSPD_100; 161 break; 162 case 10: 163 speed = EMMC_LSPD_10; 164 break; 165 default: 166 return 0; 167 } 168 169 if (!ll_temac_indirect_get(regs, TEMAC_EMMC, &emmc_reg)) 170 return 0; 171 172 emmc_reg &= ~EMMC_LSPD_MASK; 173 emmc_reg |= speed; 174 175 if (!ll_temac_indirect_set(regs, TEMAC_EMMC, emmc_reg)) 176 return 0; 177 178 printf("%s: PHY is %s with %dbase%s, %s%s\n", 179 dev->name, phydev->drv->name, 180 phydev->speed, (phydev->port == PORT_TP) ? "T" : "X", 181 (phydev->duplex) ? "FDX" : "HDX", 182 (phydev->port == PORT_OTHER) ? ", unkown mode" : ""); 183 184 return 1; 185 } 186 187 /* setup mac addr */ 188 static int ll_temac_setup_mac_addr(struct eth_device *dev) 189 { 190 struct temac_reg *regs = (struct temac_reg *)dev->iobase; 191 u32 val; 192 193 /* set up unicast MAC address filter */ 194 val = ((dev->enetaddr[3] << 24) | (dev->enetaddr[2] << 16) | 195 (dev->enetaddr[1] << 8) | (dev->enetaddr[0])); 196 val &= UAW0_UADDR_MASK; 197 198 if (!ll_temac_indirect_set(regs, TEMAC_UAW0, val)) 199 return 1; 200 201 val = ((dev->enetaddr[5] << 8) | dev->enetaddr[4]); 202 val &= UAW1_UADDR_MASK; 203 204 if (!ll_temac_indirect_set(regs, TEMAC_UAW1, val)) 205 return 1; 206 207 return 0; 208 } 209 210 /* halt device */ 211 static void ll_temac_halt(struct eth_device *dev) 212 { 213 struct ll_temac *ll_temac = dev->priv; 214 struct temac_reg *regs = (struct temac_reg *)dev->iobase; 215 216 /* Disable Receiver */ 217 ll_temac_indirect_set(regs, TEMAC_RCW0, 0); 218 219 /* Disable Transmitter */ 220 ll_temac_indirect_set(regs, TEMAC_TC, 0); 221 222 if (ll_temac->ctrlhalt) 223 ll_temac->ctrlhalt(dev); 224 225 /* Shut down the PHY, as needed */ 226 phy_shutdown(ll_temac->phydev); 227 } 228 229 static int ll_temac_init(struct eth_device *dev, bd_t *bis) 230 { 231 struct ll_temac *ll_temac = dev->priv; 232 int ret; 233 234 printf("%s: Xilinx XPS LocalLink Tri-Mode Ether MAC #%d at 0x%08X.\n", 235 dev->name, dev->index, dev->iobase); 236 237 if (!ll_temac_setup_ctrl(dev)) 238 return -1; 239 240 /* Start up the PHY */ 241 ret = phy_startup(ll_temac->phydev); 242 if (ret) { 243 printf("%s: Could not initialize PHY %s\n", 244 dev->name, ll_temac->phydev->dev->name); 245 return ret; 246 } 247 248 if (!ll_temac_adjust_link(dev)) { 249 ll_temac_halt(dev); 250 return -1; 251 } 252 253 /* If there's no link, fail */ 254 return ll_temac->phydev->link ? 0 : -1; 255 } 256 257 /* 258 * Discover which PHY is attached to the device, and configure it 259 * properly. If the PHY is not recognized, then return 0 260 * (failure). Otherwise, return 1 261 */ 262 static int ll_temac_phy_init(struct eth_device *dev) 263 { 264 struct ll_temac *ll_temac = dev->priv; 265 struct phy_device *phydev; 266 unsigned int supported = PHY_GBIT_FEATURES; 267 268 /* interface - look at driver/net/tsec.c */ 269 phydev = phy_connect(ll_temac->bus, ll_temac->phyaddr, 270 dev, PHY_INTERFACE_MODE_NONE); 271 272 phydev->supported &= supported; 273 phydev->advertising = phydev->supported; 274 275 ll_temac->phydev = phydev; 276 277 phy_config(phydev); 278 279 return 1; 280 } 281 282 /* 283 * Initialize a single ll_temac devices 284 * 285 * Returns the result of ll_temac phy interface that were initialized 286 */ 287 int xilinx_ll_temac_initialize(bd_t *bis, struct ll_temac_info *devinf) 288 { 289 struct eth_device *dev; 290 struct ll_temac *ll_temac; 291 292 dev = calloc(1, sizeof(*dev)); 293 if (dev == NULL) 294 return 0; 295 296 ll_temac = calloc(1, sizeof(struct ll_temac)); 297 if (ll_temac == NULL) { 298 free(dev); 299 return 0; 300 } 301 302 /* use given name or generate its own unique name */ 303 if (devinf->devname) { 304 strncpy(dev->name, devinf->devname, sizeof(dev->name)); 305 } else { 306 snprintf(dev->name, sizeof(dev->name), "lltemac.%lx", devinf->base_addr); 307 devinf->devname = dev->name; 308 } 309 310 dev->iobase = devinf->base_addr; 311 312 dev->priv = ll_temac; 313 dev->init = ll_temac_init; 314 dev->halt = ll_temac_halt; 315 dev->write_hwaddr = ll_temac_setup_mac_addr; 316 317 ll_temac->ctrladdr = devinf->ctrl_addr; 318 if (devinf->flags & XILINX_LL_TEMAC_M_SDMA_PLB) { 319 #if defined(CONFIG_XILINX_440) || defined(CONFIG_XILINX_405) 320 if (devinf->flags & XILINX_LL_TEMAC_M_SDMA_DCR) { 321 ll_temac_collect_xldcr_sdma_reg_addr(dev); 322 ll_temac->in32 = ll_temac_xldcr_in32; 323 ll_temac->out32 = ll_temac_xldcr_out32; 324 } else 325 #endif 326 { 327 ll_temac_collect_xlplb_sdma_reg_addr(dev); 328 ll_temac->in32 = ll_temac_xlplb_in32; 329 ll_temac->out32 = ll_temac_xlplb_out32; 330 } 331 ll_temac->ctrlinit = ll_temac_init_sdma; 332 ll_temac->ctrlhalt = ll_temac_halt_sdma; 333 ll_temac->ctrlreset = ll_temac_reset_sdma; 334 dev->recv = ll_temac_recv_sdma; 335 dev->send = ll_temac_send_sdma; 336 } else { 337 ll_temac->in32 = NULL; 338 ll_temac->out32 = NULL; 339 ll_temac->ctrlinit = NULL; 340 ll_temac->ctrlhalt = NULL; 341 ll_temac->ctrlreset = ll_temac_reset_fifo; 342 dev->recv = ll_temac_recv_fifo; 343 dev->send = ll_temac_send_fifo; 344 } 345 346 /* Link to specified MDIO bus */ 347 strncpy(ll_temac->mdio_busname, devinf->mdio_busname, MDIO_NAME_LEN); 348 ll_temac->bus = miiphy_get_dev_by_name(ll_temac->mdio_busname); 349 350 /* Looking for a valid PHY address if it is not yet set */ 351 if (devinf->phyaddr == -1) 352 ll_temac->phyaddr = ll_temac_phy_addr(ll_temac->bus); 353 else 354 ll_temac->phyaddr = devinf->phyaddr; 355 356 eth_register(dev); 357 358 /* Try to initialize PHY here, and return */ 359 return ll_temac_phy_init(dev); 360 } 361 362 /* 363 * Initialize a single ll_temac device with its mdio bus behind ll_temac 364 * 365 * Returns 1 if the ll_temac device and the mdio bus were initialized 366 * otherwise returns 0 367 */ 368 int xilinx_ll_temac_eth_init(bd_t *bis, unsigned long base_addr, int flags, 369 unsigned long ctrl_addr) 370 { 371 struct ll_temac_info devinf; 372 struct ll_temac_mdio_info mdioinf; 373 int ret; 374 375 /* prepare the internal driver informations */ 376 devinf.flags = flags; 377 devinf.base_addr = base_addr; 378 devinf.ctrl_addr = ctrl_addr; 379 devinf.devname = NULL; 380 devinf.phyaddr = -1; 381 382 mdioinf.name = devinf.mdio_busname = NULL; 383 mdioinf.regs = (struct temac_reg *)devinf.base_addr; 384 385 ret = xilinx_ll_temac_mdio_initialize(bis, &mdioinf); 386 if (ret >= 0) { 387 388 /* 389 * If there was no MDIO bus name then take over the 390 * new automaticaly generated by the MDIO init code. 391 */ 392 if (mdioinf.name != devinf.mdio_busname) 393 devinf.mdio_busname = mdioinf.name; 394 395 ret = xilinx_ll_temac_initialize(bis, &devinf); 396 if (ret > 0) 397 return 1; 398 399 } 400 401 return 0; 402 } 403