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