]>
Commit | Line | Data |
---|---|---|
4f1ec4c1 MS |
1 | /* |
2 | * Copyright (C) 2011 Michal Simek <monstr@monstr.eu> | |
3 | * Copyright (C) 2011 PetaLogix | |
4 | * Copyright (C) 2010 Xilinx, Inc. All rights reserved. | |
5 | * | |
1a459660 | 6 | * SPDX-License-Identifier: GPL-2.0+ |
4f1ec4c1 MS |
7 | */ |
8 | ||
9 | #include <config.h> | |
10 | #include <common.h> | |
75cc93fa | 11 | #include <dm.h> |
4f1ec4c1 MS |
12 | #include <net.h> |
13 | #include <malloc.h> | |
14 | #include <asm/io.h> | |
15 | #include <phy.h> | |
16 | #include <miiphy.h> | |
17 | ||
75cc93fa MS |
18 | DECLARE_GLOBAL_DATA_PTR; |
19 | ||
4f1ec4c1 MS |
20 | /* Link setup */ |
21 | #define XAE_EMMC_LINKSPEED_MASK 0xC0000000 /* Link speed */ | |
22 | #define XAE_EMMC_LINKSPD_10 0x00000000 /* Link Speed mask for 10 Mbit */ | |
23 | #define XAE_EMMC_LINKSPD_100 0x40000000 /* Link Speed mask for 100 Mbit */ | |
24 | #define XAE_EMMC_LINKSPD_1000 0x80000000 /* Link Speed mask for 1000 Mbit */ | |
25 | ||
26 | /* Interrupt Status/Enable/Mask Registers bit definitions */ | |
27 | #define XAE_INT_RXRJECT_MASK 0x00000008 /* Rx frame rejected */ | |
28 | #define XAE_INT_MGTRDY_MASK 0x00000080 /* MGT clock Lock */ | |
29 | ||
30 | /* Receive Configuration Word 1 (RCW1) Register bit definitions */ | |
31 | #define XAE_RCW1_RX_MASK 0x10000000 /* Receiver enable */ | |
32 | ||
33 | /* Transmitter Configuration (TC) Register bit definitions */ | |
34 | #define XAE_TC_TX_MASK 0x10000000 /* Transmitter enable */ | |
35 | ||
36 | #define XAE_UAW1_UNICASTADDR_MASK 0x0000FFFF | |
37 | ||
38 | /* MDIO Management Configuration (MC) Register bit definitions */ | |
39 | #define XAE_MDIO_MC_MDIOEN_MASK 0x00000040 /* MII management enable*/ | |
40 | ||
41 | /* MDIO Management Control Register (MCR) Register bit definitions */ | |
42 | #define XAE_MDIO_MCR_PHYAD_MASK 0x1F000000 /* Phy Address Mask */ | |
43 | #define XAE_MDIO_MCR_PHYAD_SHIFT 24 /* Phy Address Shift */ | |
44 | #define XAE_MDIO_MCR_REGAD_MASK 0x001F0000 /* Reg Address Mask */ | |
45 | #define XAE_MDIO_MCR_REGAD_SHIFT 16 /* Reg Address Shift */ | |
46 | #define XAE_MDIO_MCR_OP_READ_MASK 0x00008000 /* Op Code Read Mask */ | |
47 | #define XAE_MDIO_MCR_OP_WRITE_MASK 0x00004000 /* Op Code Write Mask */ | |
48 | #define XAE_MDIO_MCR_INITIATE_MASK 0x00000800 /* Ready Mask */ | |
49 | #define XAE_MDIO_MCR_READY_MASK 0x00000080 /* Ready Mask */ | |
50 | ||
51 | #define XAE_MDIO_DIV_DFT 29 /* Default MDIO clock divisor */ | |
52 | ||
53 | /* DMA macros */ | |
54 | /* Bitmasks of XAXIDMA_CR_OFFSET register */ | |
55 | #define XAXIDMA_CR_RUNSTOP_MASK 0x00000001 /* Start/stop DMA channel */ | |
56 | #define XAXIDMA_CR_RESET_MASK 0x00000004 /* Reset DMA engine */ | |
57 | ||
58 | /* Bitmasks of XAXIDMA_SR_OFFSET register */ | |
59 | #define XAXIDMA_HALTED_MASK 0x00000001 /* DMA channel halted */ | |
60 | ||
61 | /* Bitmask for interrupts */ | |
62 | #define XAXIDMA_IRQ_IOC_MASK 0x00001000 /* Completion intr */ | |
63 | #define XAXIDMA_IRQ_DELAY_MASK 0x00002000 /* Delay interrupt */ | |
64 | #define XAXIDMA_IRQ_ALL_MASK 0x00007000 /* All interrupts */ | |
65 | ||
66 | /* Bitmasks of XAXIDMA_BD_CTRL_OFFSET register */ | |
67 | #define XAXIDMA_BD_CTRL_TXSOF_MASK 0x08000000 /* First tx packet */ | |
68 | #define XAXIDMA_BD_CTRL_TXEOF_MASK 0x04000000 /* Last tx packet */ | |
69 | ||
70 | #define DMAALIGN 128 | |
71 | ||
72 | static u8 rxframe[PKTSIZE_ALIGN] __attribute((aligned(DMAALIGN))); | |
73 | ||
74 | /* Reflect dma offsets */ | |
75 | struct axidma_reg { | |
76 | u32 control; /* DMACR */ | |
77 | u32 status; /* DMASR */ | |
78 | u32 current; /* CURDESC */ | |
79 | u32 reserved; | |
80 | u32 tail; /* TAILDESC */ | |
81 | }; | |
82 | ||
83 | /* Private driver structures */ | |
84 | struct axidma_priv { | |
85 | struct axidma_reg *dmatx; | |
86 | struct axidma_reg *dmarx; | |
87 | int phyaddr; | |
6609f35b | 88 | struct axi_regs *iobase; |
75cc93fa | 89 | phy_interface_t interface; |
4f1ec4c1 MS |
90 | struct phy_device *phydev; |
91 | struct mii_dev *bus; | |
92 | }; | |
93 | ||
94 | /* BD descriptors */ | |
95 | struct axidma_bd { | |
96 | u32 next; /* Next descriptor pointer */ | |
97 | u32 reserved1; | |
98 | u32 phys; /* Buffer address */ | |
99 | u32 reserved2; | |
100 | u32 reserved3; | |
101 | u32 reserved4; | |
102 | u32 cntrl; /* Control */ | |
103 | u32 status; /* Status */ | |
104 | u32 app0; | |
105 | u32 app1; /* TX start << 16 | insert */ | |
106 | u32 app2; /* TX csum seed */ | |
107 | u32 app3; | |
108 | u32 app4; | |
109 | u32 sw_id_offset; | |
110 | u32 reserved5; | |
111 | u32 reserved6; | |
112 | }; | |
113 | ||
114 | /* Static BDs - driver uses only one BD */ | |
115 | static struct axidma_bd tx_bd __attribute((aligned(DMAALIGN))); | |
116 | static struct axidma_bd rx_bd __attribute((aligned(DMAALIGN))); | |
117 | ||
118 | struct axi_regs { | |
119 | u32 reserved[3]; | |
120 | u32 is; /* 0xC: Interrupt status */ | |
121 | u32 reserved2; | |
122 | u32 ie; /* 0x14: Interrupt enable */ | |
123 | u32 reserved3[251]; | |
124 | u32 rcw1; /* 0x404: Rx Configuration Word 1 */ | |
125 | u32 tc; /* 0x408: Tx Configuration */ | |
126 | u32 reserved4; | |
127 | u32 emmc; /* 0x410: EMAC mode configuration */ | |
128 | u32 reserved5[59]; | |
129 | u32 mdio_mc; /* 0x500: MII Management Config */ | |
130 | u32 mdio_mcr; /* 0x504: MII Management Control */ | |
131 | u32 mdio_mwd; /* 0x508: MII Management Write Data */ | |
132 | u32 mdio_mrd; /* 0x50C: MII Management Read Data */ | |
133 | u32 reserved6[124]; | |
134 | u32 uaw0; /* 0x700: Unicast address word 0 */ | |
135 | u32 uaw1; /* 0x704: Unicast address word 1 */ | |
136 | }; | |
137 | ||
138 | /* Use MII register 1 (MII status register) to detect PHY */ | |
139 | #define PHY_DETECT_REG 1 | |
140 | ||
141 | /* | |
142 | * Mask used to verify certain PHY features (or register contents) | |
143 | * in the register above: | |
144 | * 0x1000: 10Mbps full duplex support | |
145 | * 0x0800: 10Mbps half duplex support | |
146 | * 0x0008: Auto-negotiation support | |
147 | */ | |
148 | #define PHY_DETECT_MASK 0x1808 | |
149 | ||
f36bbcce | 150 | static inline int mdio_wait(struct axi_regs *regs) |
4f1ec4c1 | 151 | { |
4f1ec4c1 MS |
152 | u32 timeout = 200; |
153 | ||
154 | /* Wait till MDIO interface is ready to accept a new transaction. */ | |
155 | while (timeout && (!(in_be32(®s->mdio_mcr) | |
156 | & XAE_MDIO_MCR_READY_MASK))) { | |
157 | timeout--; | |
158 | udelay(1); | |
159 | } | |
160 | if (!timeout) { | |
161 | printf("%s: Timeout\n", __func__); | |
162 | return 1; | |
163 | } | |
164 | return 0; | |
165 | } | |
166 | ||
0d78abf5 MS |
167 | static u32 phyread(struct axidma_priv *priv, u32 phyaddress, u32 registernum, |
168 | u16 *val) | |
4f1ec4c1 | 169 | { |
0d78abf5 | 170 | struct axi_regs *regs = priv->iobase; |
4f1ec4c1 MS |
171 | u32 mdioctrlreg = 0; |
172 | ||
f36bbcce | 173 | if (mdio_wait(regs)) |
4f1ec4c1 MS |
174 | return 1; |
175 | ||
176 | mdioctrlreg = ((phyaddress << XAE_MDIO_MCR_PHYAD_SHIFT) & | |
177 | XAE_MDIO_MCR_PHYAD_MASK) | | |
178 | ((registernum << XAE_MDIO_MCR_REGAD_SHIFT) | |
179 | & XAE_MDIO_MCR_REGAD_MASK) | | |
180 | XAE_MDIO_MCR_INITIATE_MASK | | |
181 | XAE_MDIO_MCR_OP_READ_MASK; | |
182 | ||
183 | out_be32(®s->mdio_mcr, mdioctrlreg); | |
184 | ||
f36bbcce | 185 | if (mdio_wait(regs)) |
4f1ec4c1 MS |
186 | return 1; |
187 | ||
188 | /* Read data */ | |
189 | *val = in_be32(®s->mdio_mrd); | |
190 | return 0; | |
191 | } | |
192 | ||
0d78abf5 MS |
193 | static u32 phywrite(struct axidma_priv *priv, u32 phyaddress, u32 registernum, |
194 | u32 data) | |
4f1ec4c1 | 195 | { |
0d78abf5 | 196 | struct axi_regs *regs = priv->iobase; |
4f1ec4c1 MS |
197 | u32 mdioctrlreg = 0; |
198 | ||
f36bbcce | 199 | if (mdio_wait(regs)) |
4f1ec4c1 MS |
200 | return 1; |
201 | ||
202 | mdioctrlreg = ((phyaddress << XAE_MDIO_MCR_PHYAD_SHIFT) & | |
203 | XAE_MDIO_MCR_PHYAD_MASK) | | |
204 | ((registernum << XAE_MDIO_MCR_REGAD_SHIFT) | |
205 | & XAE_MDIO_MCR_REGAD_MASK) | | |
206 | XAE_MDIO_MCR_INITIATE_MASK | | |
207 | XAE_MDIO_MCR_OP_WRITE_MASK; | |
208 | ||
209 | /* Write data */ | |
210 | out_be32(®s->mdio_mwd, data); | |
211 | ||
212 | out_be32(®s->mdio_mcr, mdioctrlreg); | |
213 | ||
f36bbcce | 214 | if (mdio_wait(regs)) |
4f1ec4c1 MS |
215 | return 1; |
216 | ||
217 | return 0; | |
218 | } | |
219 | ||
5d0449d4 | 220 | static int axiemac_phy_init(struct udevice *dev) |
4f1ec4c1 MS |
221 | { |
222 | u16 phyreg; | |
5d0449d4 | 223 | u32 i, ret; |
75cc93fa | 224 | struct axidma_priv *priv = dev_get_priv(dev); |
6609f35b | 225 | struct axi_regs *regs = priv->iobase; |
4f1ec4c1 MS |
226 | struct phy_device *phydev; |
227 | ||
228 | u32 supported = SUPPORTED_10baseT_Half | | |
229 | SUPPORTED_10baseT_Full | | |
230 | SUPPORTED_100baseT_Half | | |
231 | SUPPORTED_100baseT_Full | | |
232 | SUPPORTED_1000baseT_Half | | |
233 | SUPPORTED_1000baseT_Full; | |
234 | ||
5d0449d4 MS |
235 | /* Set default MDIO divisor */ |
236 | out_be32(®s->mdio_mc, XAE_MDIO_DIV_DFT | XAE_MDIO_MC_MDIOEN_MASK); | |
237 | ||
4f1ec4c1 MS |
238 | if (priv->phyaddr == -1) { |
239 | /* Detect the PHY address */ | |
240 | for (i = 31; i >= 0; i--) { | |
0d78abf5 | 241 | ret = phyread(priv, i, PHY_DETECT_REG, &phyreg); |
4f1ec4c1 MS |
242 | if (!ret && (phyreg != 0xFFFF) && |
243 | ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { | |
244 | /* Found a valid PHY address */ | |
245 | priv->phyaddr = i; | |
246 | debug("axiemac: Found valid phy address, %x\n", | |
2652a621 | 247 | i); |
4f1ec4c1 MS |
248 | break; |
249 | } | |
250 | } | |
251 | } | |
252 | ||
253 | /* Interface - look at tsec */ | |
9c0da762 | 254 | phydev = phy_connect(priv->bus, priv->phyaddr, dev, priv->interface); |
4f1ec4c1 MS |
255 | |
256 | phydev->supported &= supported; | |
257 | phydev->advertising = phydev->supported; | |
258 | priv->phydev = phydev; | |
259 | phy_config(phydev); | |
5d0449d4 MS |
260 | |
261 | return 0; | |
262 | } | |
263 | ||
264 | /* Setting axi emac and phy to proper setting */ | |
265 | static int setup_phy(struct udevice *dev) | |
266 | { | |
8964f241 SDPP |
267 | u16 temp; |
268 | u32 speed, emmc_reg, ret; | |
5d0449d4 MS |
269 | struct axidma_priv *priv = dev_get_priv(dev); |
270 | struct axi_regs *regs = priv->iobase; | |
271 | struct phy_device *phydev = priv->phydev; | |
272 | ||
8964f241 SDPP |
273 | if (priv->interface == PHY_INTERFACE_MODE_SGMII) { |
274 | /* | |
275 | * In SGMII cases the isolate bit might set | |
276 | * after DMA and ethernet resets and hence | |
277 | * check and clear if set. | |
278 | */ | |
279 | ret = phyread(priv, priv->phyaddr, MII_BMCR, &temp); | |
280 | if (ret) | |
281 | return 0; | |
282 | if (temp & BMCR_ISOLATE) { | |
283 | temp &= ~BMCR_ISOLATE; | |
284 | ret = phywrite(priv, priv->phyaddr, MII_BMCR, temp); | |
285 | if (ret) | |
286 | return 0; | |
287 | } | |
288 | } | |
289 | ||
11af8d65 TT |
290 | if (phy_startup(phydev)) { |
291 | printf("axiemac: could not initialize PHY %s\n", | |
292 | phydev->dev->name); | |
293 | return 0; | |
294 | } | |
6f9b9372 MS |
295 | if (!phydev->link) { |
296 | printf("%s: No link.\n", phydev->dev->name); | |
297 | return 0; | |
298 | } | |
4f1ec4c1 MS |
299 | |
300 | switch (phydev->speed) { | |
301 | case 1000: | |
302 | speed = XAE_EMMC_LINKSPD_1000; | |
303 | break; | |
304 | case 100: | |
305 | speed = XAE_EMMC_LINKSPD_100; | |
306 | break; | |
307 | case 10: | |
308 | speed = XAE_EMMC_LINKSPD_10; | |
309 | break; | |
310 | default: | |
311 | return 0; | |
312 | } | |
313 | ||
314 | /* Setup the emac for the phy speed */ | |
315 | emmc_reg = in_be32(®s->emmc); | |
316 | emmc_reg &= ~XAE_EMMC_LINKSPEED_MASK; | |
317 | emmc_reg |= speed; | |
318 | ||
319 | /* Write new speed setting out to Axi Ethernet */ | |
320 | out_be32(®s->emmc, emmc_reg); | |
321 | ||
322 | /* | |
323 | * Setting the operating speed of the MAC needs a delay. There | |
324 | * doesn't seem to be register to poll, so please consider this | |
325 | * during your application design. | |
326 | */ | |
327 | udelay(1); | |
328 | ||
329 | return 1; | |
330 | } | |
331 | ||
332 | /* STOP DMA transfers */ | |
ad499e42 | 333 | static void axiemac_stop(struct udevice *dev) |
4f1ec4c1 | 334 | { |
75cc93fa | 335 | struct axidma_priv *priv = dev_get_priv(dev); |
4f1ec4c1 MS |
336 | u32 temp; |
337 | ||
338 | /* Stop the hardware */ | |
339 | temp = in_be32(&priv->dmatx->control); | |
340 | temp &= ~XAXIDMA_CR_RUNSTOP_MASK; | |
341 | out_be32(&priv->dmatx->control, temp); | |
342 | ||
343 | temp = in_be32(&priv->dmarx->control); | |
344 | temp &= ~XAXIDMA_CR_RUNSTOP_MASK; | |
345 | out_be32(&priv->dmarx->control, temp); | |
346 | ||
347 | debug("axiemac: Halted\n"); | |
348 | } | |
349 | ||
f0985481 | 350 | static int axi_ethernet_init(struct axidma_priv *priv) |
4f1ec4c1 | 351 | { |
f0985481 | 352 | struct axi_regs *regs = priv->iobase; |
4f1ec4c1 MS |
353 | u32 timeout = 200; |
354 | ||
355 | /* | |
356 | * Check the status of the MgtRdy bit in the interrupt status | |
357 | * registers. This must be done to allow the MGT clock to become stable | |
358 | * for the Sgmii and 1000BaseX PHY interfaces. No other register reads | |
359 | * will be valid until this bit is valid. | |
360 | * The bit is always a 1 for all other PHY interfaces. | |
361 | */ | |
362 | while (timeout && (!(in_be32(®s->is) & XAE_INT_MGTRDY_MASK))) { | |
363 | timeout--; | |
364 | udelay(1); | |
365 | } | |
366 | if (!timeout) { | |
367 | printf("%s: Timeout\n", __func__); | |
368 | return 1; | |
369 | } | |
370 | ||
371 | /* Stop the device and reset HW */ | |
372 | /* Disable interrupts */ | |
373 | out_be32(®s->ie, 0); | |
374 | ||
375 | /* Disable the receiver */ | |
376 | out_be32(®s->rcw1, in_be32(®s->rcw1) & ~XAE_RCW1_RX_MASK); | |
377 | ||
378 | /* | |
379 | * Stopping the receiver in mid-packet causes a dropped packet | |
380 | * indication from HW. Clear it. | |
381 | */ | |
382 | /* Set the interrupt status register to clear the interrupt */ | |
383 | out_be32(®s->is, XAE_INT_RXRJECT_MASK); | |
384 | ||
385 | /* Setup HW */ | |
386 | /* Set default MDIO divisor */ | |
387 | out_be32(®s->mdio_mc, XAE_MDIO_DIV_DFT | XAE_MDIO_MC_MDIOEN_MASK); | |
388 | ||
389 | debug("axiemac: InitHw done\n"); | |
390 | return 0; | |
391 | } | |
392 | ||
ad499e42 | 393 | static int axiemac_write_hwaddr(struct udevice *dev) |
4f1ec4c1 | 394 | { |
75cc93fa MS |
395 | struct eth_pdata *pdata = dev_get_platdata(dev); |
396 | struct axidma_priv *priv = dev_get_priv(dev); | |
397 | struct axi_regs *regs = priv->iobase; | |
4f1ec4c1 MS |
398 | |
399 | /* Set the MAC address */ | |
75cc93fa MS |
400 | int val = ((pdata->enetaddr[3] << 24) | (pdata->enetaddr[2] << 16) | |
401 | (pdata->enetaddr[1] << 8) | (pdata->enetaddr[0])); | |
4f1ec4c1 MS |
402 | out_be32(®s->uaw0, val); |
403 | ||
75cc93fa | 404 | val = (pdata->enetaddr[5] << 8) | pdata->enetaddr[4]; |
4f1ec4c1 MS |
405 | val |= in_be32(®s->uaw1) & ~XAE_UAW1_UNICASTADDR_MASK; |
406 | out_be32(®s->uaw1, val); | |
407 | return 0; | |
408 | } | |
409 | ||
410 | /* Reset DMA engine */ | |
f0985481 | 411 | static void axi_dma_init(struct axidma_priv *priv) |
4f1ec4c1 | 412 | { |
4f1ec4c1 MS |
413 | u32 timeout = 500; |
414 | ||
415 | /* Reset the engine so the hardware starts from a known state */ | |
416 | out_be32(&priv->dmatx->control, XAXIDMA_CR_RESET_MASK); | |
417 | out_be32(&priv->dmarx->control, XAXIDMA_CR_RESET_MASK); | |
418 | ||
419 | /* At the initialization time, hardware should finish reset quickly */ | |
420 | while (timeout--) { | |
421 | /* Check transmit/receive channel */ | |
422 | /* Reset is done when the reset bit is low */ | |
3e3f8ba2 | 423 | if (!((in_be32(&priv->dmatx->control) | |
4f1ec4c1 | 424 | in_be32(&priv->dmarx->control)) |
3e3f8ba2 | 425 | & XAXIDMA_CR_RESET_MASK)) { |
4f1ec4c1 MS |
426 | break; |
427 | } | |
428 | } | |
429 | if (!timeout) | |
430 | printf("%s: Timeout\n", __func__); | |
431 | } | |
432 | ||
ad499e42 | 433 | static int axiemac_start(struct udevice *dev) |
4f1ec4c1 | 434 | { |
75cc93fa MS |
435 | struct axidma_priv *priv = dev_get_priv(dev); |
436 | struct axi_regs *regs = priv->iobase; | |
4f1ec4c1 MS |
437 | u32 temp; |
438 | ||
439 | debug("axiemac: Init started\n"); | |
440 | /* | |
441 | * Initialize AXIDMA engine. AXIDMA engine must be initialized before | |
442 | * AxiEthernet. During AXIDMA engine initialization, AXIDMA hardware is | |
443 | * reset, and since AXIDMA reset line is connected to AxiEthernet, this | |
444 | * would ensure a reset of AxiEthernet. | |
445 | */ | |
f0985481 | 446 | axi_dma_init(priv); |
4f1ec4c1 MS |
447 | |
448 | /* Initialize AxiEthernet hardware. */ | |
f0985481 | 449 | if (axi_ethernet_init(priv)) |
4f1ec4c1 MS |
450 | return -1; |
451 | ||
452 | /* Disable all RX interrupts before RxBD space setup */ | |
453 | temp = in_be32(&priv->dmarx->control); | |
454 | temp &= ~XAXIDMA_IRQ_ALL_MASK; | |
455 | out_be32(&priv->dmarx->control, temp); | |
456 | ||
457 | /* Start DMA RX channel. Now it's ready to receive data.*/ | |
458 | out_be32(&priv->dmarx->current, (u32)&rx_bd); | |
459 | ||
460 | /* Setup the BD. */ | |
461 | memset(&rx_bd, 0, sizeof(rx_bd)); | |
462 | rx_bd.next = (u32)&rx_bd; | |
463 | rx_bd.phys = (u32)&rxframe; | |
464 | rx_bd.cntrl = sizeof(rxframe); | |
465 | /* Flush the last BD so DMA core could see the updates */ | |
466 | flush_cache((u32)&rx_bd, sizeof(rx_bd)); | |
467 | ||
468 | /* It is necessary to flush rxframe because if you don't do it | |
469 | * then cache can contain uninitialized data */ | |
470 | flush_cache((u32)&rxframe, sizeof(rxframe)); | |
471 | ||
472 | /* Start the hardware */ | |
473 | temp = in_be32(&priv->dmarx->control); | |
474 | temp |= XAXIDMA_CR_RUNSTOP_MASK; | |
475 | out_be32(&priv->dmarx->control, temp); | |
476 | ||
477 | /* Rx BD is ready - start */ | |
478 | out_be32(&priv->dmarx->tail, (u32)&rx_bd); | |
479 | ||
480 | /* Enable TX */ | |
481 | out_be32(®s->tc, XAE_TC_TX_MASK); | |
482 | /* Enable RX */ | |
483 | out_be32(®s->rcw1, XAE_RCW1_RX_MASK); | |
484 | ||
485 | /* PHY setup */ | |
486 | if (!setup_phy(dev)) { | |
ad499e42 | 487 | axiemac_stop(dev); |
4f1ec4c1 MS |
488 | return -1; |
489 | } | |
490 | ||
491 | debug("axiemac: Init complete\n"); | |
492 | return 0; | |
493 | } | |
494 | ||
75cc93fa | 495 | static int axiemac_send(struct udevice *dev, void *ptr, int len) |
4f1ec4c1 | 496 | { |
75cc93fa | 497 | struct axidma_priv *priv = dev_get_priv(dev); |
4f1ec4c1 MS |
498 | u32 timeout; |
499 | ||
500 | if (len > PKTSIZE_ALIGN) | |
501 | len = PKTSIZE_ALIGN; | |
502 | ||
503 | /* Flush packet to main memory to be trasfered by DMA */ | |
504 | flush_cache((u32)ptr, len); | |
505 | ||
506 | /* Setup Tx BD */ | |
507 | memset(&tx_bd, 0, sizeof(tx_bd)); | |
508 | /* At the end of the ring, link the last BD back to the top */ | |
509 | tx_bd.next = (u32)&tx_bd; | |
510 | tx_bd.phys = (u32)ptr; | |
511 | /* Save len */ | |
512 | tx_bd.cntrl = len | XAXIDMA_BD_CTRL_TXSOF_MASK | | |
513 | XAXIDMA_BD_CTRL_TXEOF_MASK; | |
514 | ||
515 | /* Flush the last BD so DMA core could see the updates */ | |
516 | flush_cache((u32)&tx_bd, sizeof(tx_bd)); | |
517 | ||
518 | if (in_be32(&priv->dmatx->status) & XAXIDMA_HALTED_MASK) { | |
519 | u32 temp; | |
520 | out_be32(&priv->dmatx->current, (u32)&tx_bd); | |
521 | /* Start the hardware */ | |
522 | temp = in_be32(&priv->dmatx->control); | |
523 | temp |= XAXIDMA_CR_RUNSTOP_MASK; | |
524 | out_be32(&priv->dmatx->control, temp); | |
525 | } | |
526 | ||
527 | /* Start transfer */ | |
528 | out_be32(&priv->dmatx->tail, (u32)&tx_bd); | |
529 | ||
530 | /* Wait for transmission to complete */ | |
531 | debug("axiemac: Waiting for tx to be done\n"); | |
532 | timeout = 200; | |
3e3f8ba2 MS |
533 | while (timeout && (!(in_be32(&priv->dmatx->status) & |
534 | (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK)))) { | |
4f1ec4c1 MS |
535 | timeout--; |
536 | udelay(1); | |
537 | } | |
538 | if (!timeout) { | |
539 | printf("%s: Timeout\n", __func__); | |
540 | return 1; | |
541 | } | |
542 | ||
543 | debug("axiemac: Sending complete\n"); | |
544 | return 0; | |
545 | } | |
546 | ||
f0985481 | 547 | static int isrxready(struct axidma_priv *priv) |
4f1ec4c1 MS |
548 | { |
549 | u32 status; | |
4f1ec4c1 MS |
550 | |
551 | /* Read pending interrupts */ | |
552 | status = in_be32(&priv->dmarx->status); | |
553 | ||
554 | /* Acknowledge pending interrupts */ | |
555 | out_be32(&priv->dmarx->status, status & XAXIDMA_IRQ_ALL_MASK); | |
556 | ||
557 | /* | |
558 | * If Reception done interrupt is asserted, call RX call back function | |
559 | * to handle the processed BDs and then raise the according flag. | |
560 | */ | |
561 | if ((status & (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK))) | |
562 | return 1; | |
563 | ||
564 | return 0; | |
565 | } | |
566 | ||
75cc93fa | 567 | static int axiemac_recv(struct udevice *dev, int flags, uchar **packetp) |
4f1ec4c1 MS |
568 | { |
569 | u32 length; | |
75cc93fa | 570 | struct axidma_priv *priv = dev_get_priv(dev); |
4f1ec4c1 MS |
571 | u32 temp; |
572 | ||
573 | /* Wait for an incoming packet */ | |
f0985481 | 574 | if (!isrxready(priv)) |
75cc93fa | 575 | return -1; |
4f1ec4c1 MS |
576 | |
577 | debug("axiemac: RX data ready\n"); | |
578 | ||
579 | /* Disable IRQ for a moment till packet is handled */ | |
580 | temp = in_be32(&priv->dmarx->control); | |
581 | temp &= ~XAXIDMA_IRQ_ALL_MASK; | |
582 | out_be32(&priv->dmarx->control, temp); | |
583 | ||
584 | length = rx_bd.app4 & 0xFFFF; /* max length mask */ | |
585 | #ifdef DEBUG | |
586 | print_buffer(&rxframe, &rxframe[0], 1, length, 16); | |
587 | #endif | |
97d2363d MS |
588 | |
589 | *packetp = rxframe; | |
590 | return length; | |
591 | } | |
592 | ||
593 | static int axiemac_free_pkt(struct udevice *dev, uchar *packet, int length) | |
594 | { | |
595 | struct axidma_priv *priv = dev_get_priv(dev); | |
4f1ec4c1 MS |
596 | |
597 | #ifdef DEBUG | |
598 | /* It is useful to clear buffer to be sure that it is consistent */ | |
599 | memset(rxframe, 0, sizeof(rxframe)); | |
600 | #endif | |
601 | /* Setup RxBD */ | |
602 | /* Clear the whole buffer and setup it again - all flags are cleared */ | |
603 | memset(&rx_bd, 0, sizeof(rx_bd)); | |
604 | rx_bd.next = (u32)&rx_bd; | |
605 | rx_bd.phys = (u32)&rxframe; | |
606 | rx_bd.cntrl = sizeof(rxframe); | |
607 | ||
608 | /* Write bd to HW */ | |
609 | flush_cache((u32)&rx_bd, sizeof(rx_bd)); | |
610 | ||
611 | /* It is necessary to flush rxframe because if you don't do it | |
612 | * then cache will contain previous packet */ | |
613 | flush_cache((u32)&rxframe, sizeof(rxframe)); | |
614 | ||
615 | /* Rx BD is ready - start again */ | |
616 | out_be32(&priv->dmarx->tail, (u32)&rx_bd); | |
617 | ||
618 | debug("axiemac: RX completed, framelength = %d\n", length); | |
619 | ||
75cc93fa | 620 | return 0; |
4f1ec4c1 MS |
621 | } |
622 | ||
75cc93fa MS |
623 | static int axiemac_miiphy_read(struct mii_dev *bus, int addr, |
624 | int devad, int reg) | |
4f1ec4c1 | 625 | { |
75cc93fa MS |
626 | int ret; |
627 | u16 value; | |
4f1ec4c1 | 628 | |
75cc93fa MS |
629 | ret = phyread(bus->priv, addr, reg, &value); |
630 | debug("axiemac: Read MII 0x%x, 0x%x, 0x%x, %d\n", addr, reg, | |
631 | value, ret); | |
632 | return value; | |
4f1ec4c1 MS |
633 | } |
634 | ||
75cc93fa MS |
635 | static int axiemac_miiphy_write(struct mii_dev *bus, int addr, int devad, |
636 | int reg, u16 value) | |
4f1ec4c1 | 637 | { |
75cc93fa MS |
638 | debug("axiemac: Write MII 0x%x, 0x%x, 0x%x\n", addr, reg, value); |
639 | return phywrite(bus->priv, addr, reg, value); | |
4f1ec4c1 MS |
640 | } |
641 | ||
75cc93fa | 642 | static int axi_emac_probe(struct udevice *dev) |
4f1ec4c1 | 643 | { |
75cc93fa MS |
644 | struct axidma_priv *priv = dev_get_priv(dev); |
645 | int ret; | |
646 | ||
647 | priv->bus = mdio_alloc(); | |
648 | priv->bus->read = axiemac_miiphy_read; | |
649 | priv->bus->write = axiemac_miiphy_write; | |
650 | priv->bus->priv = priv; | |
651 | strcpy(priv->bus->name, "axi_emac"); | |
652 | ||
653 | ret = mdio_register(priv->bus); | |
654 | if (ret) | |
655 | return ret; | |
656 | ||
5d0449d4 MS |
657 | axiemac_phy_init(dev); |
658 | ||
4f1ec4c1 MS |
659 | return 0; |
660 | } | |
661 | ||
75cc93fa | 662 | static int axi_emac_remove(struct udevice *dev) |
4f1ec4c1 | 663 | { |
75cc93fa | 664 | struct axidma_priv *priv = dev_get_priv(dev); |
4f1ec4c1 | 665 | |
75cc93fa MS |
666 | free(priv->phydev); |
667 | mdio_unregister(priv->bus); | |
668 | mdio_free(priv->bus); | |
4f1ec4c1 | 669 | |
75cc93fa MS |
670 | return 0; |
671 | } | |
4f1ec4c1 | 672 | |
75cc93fa | 673 | static const struct eth_ops axi_emac_ops = { |
ad499e42 | 674 | .start = axiemac_start, |
75cc93fa MS |
675 | .send = axiemac_send, |
676 | .recv = axiemac_recv, | |
97d2363d | 677 | .free_pkt = axiemac_free_pkt, |
ad499e42 MS |
678 | .stop = axiemac_stop, |
679 | .write_hwaddr = axiemac_write_hwaddr, | |
75cc93fa | 680 | }; |
4f1ec4c1 | 681 | |
75cc93fa MS |
682 | static int axi_emac_ofdata_to_platdata(struct udevice *dev) |
683 | { | |
684 | struct eth_pdata *pdata = dev_get_platdata(dev); | |
685 | struct axidma_priv *priv = dev_get_priv(dev); | |
686 | int offset = 0; | |
687 | const char *phy_mode; | |
688 | ||
689 | pdata->iobase = (phys_addr_t)dev_get_addr(dev); | |
690 | priv->iobase = (struct axi_regs *)pdata->iobase; | |
691 | ||
692 | offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, | |
693 | "axistream-connected"); | |
694 | if (offset <= 0) { | |
695 | printf("%s: axistream is not found\n", __func__); | |
696 | return -EINVAL; | |
697 | } | |
698 | priv->dmatx = (struct axidma_reg *)fdtdec_get_int(gd->fdt_blob, | |
699 | offset, "reg", 0); | |
700 | if (!priv->dmatx) { | |
701 | printf("%s: axi_dma register space not found\n", __func__); | |
702 | return -EINVAL; | |
703 | } | |
4f1ec4c1 | 704 | /* RX channel offset is 0x30 */ |
75cc93fa MS |
705 | priv->dmarx = (struct axidma_reg *)((u32)priv->dmatx + 0x30); |
706 | ||
4f1ec4c1 | 707 | priv->phyaddr = -1; |
4f1ec4c1 | 708 | |
75cc93fa MS |
709 | offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, |
710 | "phy-handle"); | |
711 | if (offset > 0) | |
712 | priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1); | |
713 | ||
714 | phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL); | |
715 | if (phy_mode) | |
716 | pdata->phy_interface = phy_get_interface_by_name(phy_mode); | |
717 | if (pdata->phy_interface == -1) { | |
718 | debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode); | |
719 | return -EINVAL; | |
720 | } | |
721 | priv->interface = pdata->phy_interface; | |
4f1ec4c1 | 722 | |
75cc93fa MS |
723 | printf("AXI EMAC: %lx, phyaddr %d, interface %s\n", (ulong)priv->iobase, |
724 | priv->phyaddr, phy_string_for_interface(priv->interface)); | |
725 | ||
726 | return 0; | |
4f1ec4c1 | 727 | } |
75cc93fa MS |
728 | |
729 | static const struct udevice_id axi_emac_ids[] = { | |
730 | { .compatible = "xlnx,axi-ethernet-1.00.a" }, | |
731 | { } | |
732 | }; | |
733 | ||
734 | U_BOOT_DRIVER(axi_emac) = { | |
735 | .name = "axi_emac", | |
736 | .id = UCLASS_ETH, | |
737 | .of_match = axi_emac_ids, | |
738 | .ofdata_to_platdata = axi_emac_ofdata_to_platdata, | |
739 | .probe = axi_emac_probe, | |
740 | .remove = axi_emac_remove, | |
741 | .ops = &axi_emac_ops, | |
742 | .priv_auto_alloc_size = sizeof(struct axidma_priv), | |
743 | .platdata_auto_alloc_size = sizeof(struct eth_pdata), | |
744 | }; |