2 * Xilinx xps_ll_temac ethernet driver for u-boot
4 * supports SDMA or FIFO access and MDIO bus communication
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
10 * Based on Yoshio Kashiwagi kashiwagi@co-nss.co.jp driver
11 * Copyright (C) 2008 Nissin Systems Co.,Ltd.
14 * SPDX-License-Identifier: GPL-2.0+
16 * [0]: http://www.xilinx.com/support/documentation
18 * [S]: [0]/ip_documentation/xps_ll_temac.pdf
19 * [A]: [0]/application_notes/xapp1041.pdf
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"
35 #if !defined(CONFIG_MII)
36 # error "LL_TEMAC requires MII -- missing CONFIG_MII"
39 #if !defined(CONFIG_PHYLIB)
40 # error "LL_TEMAC requires PHYLIB -- missing CONFIG_PHYLIB"
43 struct ll_temac_info
{
45 unsigned long base_addr
;
46 unsigned long ctrl_addr
;
52 /* Ethernet interface ready status */
53 int ll_temac_check_status(struct temac_reg
*regs
, u32 mask
)
55 unsigned timeout
= 50; /* 1usec * 50 = 50usec */
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.
64 while (timeout
&& (!(in_be32(®s
->rdy
) & mask
))) {
70 printf("%s: Timeout on 0x%08x @%p\n", __func__
,
79 * Indirect write to ll_temac.
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
84 int ll_temac_indirect_set(struct temac_reg
*regs
, u16 regn
, u32 reg_data
)
86 out_be32(®s
->lsw
, (reg_data
& MLSW_MASK
));
87 out_be32(®s
->ctl
, CTL_WEN
| (regn
& CTL_ADDR_MASK
));
89 if (ll_temac_check_status(regs
, RSE_CFG_WR
))
96 * Indirect read from ll_temac.
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
101 int ll_temac_indirect_get(struct temac_reg
*regs
, u16 regn
, u32
* reg_data
)
103 out_be32(®s
->ctl
, (regn
& CTL_ADDR_MASK
));
105 if (ll_temac_check_status(regs
, RSE_CFG_RR
))
108 *reg_data
= in_be32(®s
->lsw
) & MLSW_MASK
;
112 /* setting sub-controller and ll_temac to proper setting */
113 static int ll_temac_setup_ctrl(struct eth_device
*dev
)
115 struct ll_temac
*ll_temac
= dev
->priv
;
116 struct temac_reg
*regs
= (struct temac_reg
*)dev
->iobase
;
118 if (ll_temac
->ctrlreset
&& ll_temac
->ctrlreset(dev
))
121 if (ll_temac
->ctrlinit
&& ll_temac
->ctrlinit(dev
))
124 /* Promiscuous mode disable */
125 if (!ll_temac_indirect_set(regs
, TEMAC_AFM
, 0))
128 /* Enable Receiver - RX bit */
129 if (!ll_temac_indirect_set(regs
, TEMAC_RCW1
, RCW1_RX
))
132 /* Enable Transmitter - TX bit */
133 if (!ll_temac_indirect_set(regs
, TEMAC_TC
, TC_TX
))
140 * Configure ll_temac based on negotiated speed and duplex
141 * reported by PHY handling code
143 static int ll_temac_adjust_link(struct eth_device
*dev
)
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
;
151 printf("%s: No link.\n", phydev
->dev
->name
);
155 switch (phydev
->speed
) {
157 speed
= EMMC_LSPD_1000
;
160 speed
= EMMC_LSPD_100
;
163 speed
= EMMC_LSPD_10
;
169 if (!ll_temac_indirect_get(regs
, TEMAC_EMMC
, &emmc_reg
))
172 emmc_reg
&= ~EMMC_LSPD_MASK
;
175 if (!ll_temac_indirect_set(regs
, TEMAC_EMMC
, emmc_reg
))
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" : "");
188 static int ll_temac_setup_mac_addr(struct eth_device
*dev
)
190 struct temac_reg
*regs
= (struct temac_reg
*)dev
->iobase
;
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
;
198 if (!ll_temac_indirect_set(regs
, TEMAC_UAW0
, val
))
201 val
= ((dev
->enetaddr
[5] << 8) | dev
->enetaddr
[4]);
202 val
&= UAW1_UADDR_MASK
;
204 if (!ll_temac_indirect_set(regs
, TEMAC_UAW1
, val
))
211 static void ll_temac_halt(struct eth_device
*dev
)
213 struct ll_temac
*ll_temac
= dev
->priv
;
214 struct temac_reg
*regs
= (struct temac_reg
*)dev
->iobase
;
216 /* Disable Receiver */
217 ll_temac_indirect_set(regs
, TEMAC_RCW0
, 0);
219 /* Disable Transmitter */
220 ll_temac_indirect_set(regs
, TEMAC_TC
, 0);
222 if (ll_temac
->ctrlhalt
)
223 ll_temac
->ctrlhalt(dev
);
225 /* Shut down the PHY, as needed */
226 phy_shutdown(ll_temac
->phydev
);
229 static int ll_temac_init(struct eth_device
*dev
, bd_t
*bis
)
231 struct ll_temac
*ll_temac
= dev
->priv
;
234 printf("%s: Xilinx XPS LocalLink Tri-Mode Ether MAC #%d at 0x%08lx.\n",
235 dev
->name
, dev
->index
, dev
->iobase
);
237 if (!ll_temac_setup_ctrl(dev
))
240 /* Start up the PHY */
241 ret
= phy_startup(ll_temac
->phydev
);
243 printf("%s: Could not initialize PHY %s\n",
244 dev
->name
, ll_temac
->phydev
->dev
->name
);
248 if (!ll_temac_adjust_link(dev
)) {
253 /* If there's no link, fail */
254 return ll_temac
->phydev
->link
? 0 : -1;
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
262 static int ll_temac_phy_init(struct eth_device
*dev
)
264 struct ll_temac
*ll_temac
= dev
->priv
;
265 struct phy_device
*phydev
;
266 unsigned int supported
= PHY_GBIT_FEATURES
;
268 /* interface - look at driver/net/tsec.c */
269 phydev
= phy_connect(ll_temac
->bus
, ll_temac
->phyaddr
,
270 dev
, PHY_INTERFACE_MODE_NONE
);
272 phydev
->supported
&= supported
;
273 phydev
->advertising
= phydev
->supported
;
275 ll_temac
->phydev
= phydev
;
283 * Initialize a single ll_temac devices
285 * Returns the result of ll_temac phy interface that were initialized
287 int xilinx_ll_temac_initialize(bd_t
*bis
, struct ll_temac_info
*devinf
)
289 struct eth_device
*dev
;
290 struct ll_temac
*ll_temac
;
292 dev
= calloc(1, sizeof(*dev
));
296 ll_temac
= calloc(1, sizeof(struct ll_temac
));
297 if (ll_temac
== NULL
) {
302 /* use given name or generate its own unique name */
303 if (devinf
->devname
) {
304 strncpy(dev
->name
, devinf
->devname
, sizeof(dev
->name
));
306 snprintf(dev
->name
, sizeof(dev
->name
), "ll_tem.%lx",
308 devinf
->devname
= dev
->name
;
311 dev
->iobase
= devinf
->base_addr
;
313 dev
->priv
= ll_temac
;
314 dev
->init
= ll_temac_init
;
315 dev
->halt
= ll_temac_halt
;
316 dev
->write_hwaddr
= ll_temac_setup_mac_addr
;
318 ll_temac
->ctrladdr
= devinf
->ctrl_addr
;
319 if (devinf
->flags
& XILINX_LL_TEMAC_M_SDMA_PLB
) {
320 ll_temac_collect_xlplb_sdma_reg_addr(dev
);
321 ll_temac
->in32
= ll_temac_xlplb_in32
;
322 ll_temac
->out32
= ll_temac_xlplb_out32
;
323 ll_temac
->ctrlinit
= ll_temac_init_sdma
;
324 ll_temac
->ctrlhalt
= ll_temac_halt_sdma
;
325 ll_temac
->ctrlreset
= ll_temac_reset_sdma
;
326 dev
->recv
= ll_temac_recv_sdma
;
327 dev
->send
= ll_temac_send_sdma
;
329 ll_temac
->in32
= NULL
;
330 ll_temac
->out32
= NULL
;
331 ll_temac
->ctrlinit
= NULL
;
332 ll_temac
->ctrlhalt
= NULL
;
333 ll_temac
->ctrlreset
= ll_temac_reset_fifo
;
334 dev
->recv
= ll_temac_recv_fifo
;
335 dev
->send
= ll_temac_send_fifo
;
338 /* Link to specified MDIO bus */
339 strncpy(ll_temac
->mdio_busname
, devinf
->mdio_busname
, MDIO_NAME_LEN
);
340 ll_temac
->bus
= miiphy_get_dev_by_name(ll_temac
->mdio_busname
);
342 /* Looking for a valid PHY address if it is not yet set */
343 if (devinf
->phyaddr
== -1)
344 ll_temac
->phyaddr
= ll_temac_phy_addr(ll_temac
->bus
);
346 ll_temac
->phyaddr
= devinf
->phyaddr
;
350 /* Try to initialize PHY here, and return */
351 return ll_temac_phy_init(dev
);
355 * Initialize a single ll_temac device with its mdio bus behind ll_temac
357 * Returns 1 if the ll_temac device and the mdio bus were initialized
358 * otherwise returns 0
360 int xilinx_ll_temac_eth_init(bd_t
*bis
, unsigned long base_addr
, int flags
,
361 unsigned long ctrl_addr
)
363 struct ll_temac_info devinf
;
364 struct ll_temac_mdio_info mdioinf
;
367 /* prepare the internal driver informations */
368 devinf
.flags
= flags
;
369 devinf
.base_addr
= base_addr
;
370 devinf
.ctrl_addr
= ctrl_addr
;
371 devinf
.devname
= NULL
;
374 mdioinf
.name
= devinf
.mdio_busname
= NULL
;
375 mdioinf
.regs
= (struct temac_reg
*)devinf
.base_addr
;
377 ret
= xilinx_ll_temac_mdio_initialize(bis
, &mdioinf
);
381 * If there was no MDIO bus name then take over the
382 * new automaticaly generated by the MDIO init code.
384 if (mdioinf
.name
!= devinf
.mdio_busname
)
385 devinf
.mdio_busname
= mdioinf
.name
;
387 ret
= xilinx_ll_temac_initialize(bis
, &devinf
);