2 * Altera 10/100/1000 triple speed ethernet mac driver
4 * Copyright (C) 2008 Altera Corporation.
5 * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
14 #include <fdt_support.h>
18 #include <asm/cache.h>
19 #include <asm/dma-mapping.h>
21 #include "altera_tse.h"
23 DECLARE_GLOBAL_DATA_PTR
;
25 static inline void alt_sgdma_construct_descriptor(
26 struct alt_sgdma_descriptor
*desc
,
27 struct alt_sgdma_descriptor
*next
,
33 int write_fixed_or_sop
)
38 * Mark the "next" descriptor as "not" owned by hardware. This prevents
39 * The SGDMA controller from continuing to process the chain.
41 next
->descriptor_control
= next
->descriptor_control
&
42 ~ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK
;
44 memset(desc
, 0, sizeof(struct alt_sgdma_descriptor
));
45 desc
->source
= virt_to_phys(read_addr
);
46 desc
->destination
= virt_to_phys(write_addr
);
47 desc
->next
= virt_to_phys(next
);
48 desc
->bytes_to_transfer
= length_or_eop
;
51 * Set the descriptor control block as follows:
52 * - Set "owned by hardware" bit
53 * - Optionally set "generate EOP" bit
54 * - Optionally set the "read from fixed address" bit
55 * - Optionally set the "write to fixed address bit (which serves
56 * serves as a "generate SOP" control bit in memory-to-stream mode).
57 * - Set the 4-bit atlantic channel, if specified
59 * Note this step is performed after all other descriptor information
60 * has been filled out so that, if the controller already happens to be
61 * pointing at this descriptor, it will not run (via the "owned by
62 * hardware" bit) until all other descriptor has been set up.
64 val
= ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK
;
66 val
|= ALT_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK
;
68 val
|= ALT_SGDMA_DESCRIPTOR_CONTROL_READ_FIXED_ADDRESS_MSK
;
69 if (write_fixed_or_sop
)
70 val
|= ALT_SGDMA_DESCRIPTOR_CONTROL_WRITE_FIXED_ADDRESS_MSK
;
71 desc
->descriptor_control
= val
;
74 static int alt_sgdma_wait_transfer(struct alt_sgdma_registers
*regs
)
79 /* Wait for the descriptor (chain) to complete */
82 status
= readl(®s
->status
);
83 if (!(status
& ALT_SGDMA_STATUS_BUSY_MSK
))
85 if (get_timer(ctime
) > ALT_TSE_SGDMA_BUSY_TIMEOUT
) {
87 debug("sgdma timeout\n");
93 writel(0, ®s
->control
);
95 writel(0xff, ®s
->status
);
100 static int alt_sgdma_start_transfer(struct alt_sgdma_registers
*regs
,
101 struct alt_sgdma_descriptor
*desc
)
105 /* Point the controller at the descriptor */
106 writel(virt_to_phys(desc
), ®s
->next_descriptor_pointer
);
109 * Set up SGDMA controller to:
110 * - Disable interrupt generation
111 * - Run once a valid descriptor is written to controller
112 * - Stop on an error with any particular descriptor
114 val
= ALT_SGDMA_CONTROL_RUN_MSK
| ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK
;
115 writel(val
, ®s
->control
);
120 static void tse_adjust_link(struct altera_tse_priv
*priv
,
121 struct phy_device
*phydev
)
123 struct alt_tse_mac
*mac_dev
= priv
->mac_dev
;
127 debug("%s: No link.\n", phydev
->dev
->name
);
131 refvar
= readl(&mac_dev
->command_config
);
134 refvar
|= ALTERA_TSE_CMD_HD_ENA_MSK
;
136 refvar
&= ~ALTERA_TSE_CMD_HD_ENA_MSK
;
138 switch (phydev
->speed
) {
140 refvar
|= ALTERA_TSE_CMD_ETH_SPEED_MSK
;
141 refvar
&= ~ALTERA_TSE_CMD_ENA_10_MSK
;
144 refvar
&= ~ALTERA_TSE_CMD_ETH_SPEED_MSK
;
145 refvar
&= ~ALTERA_TSE_CMD_ENA_10_MSK
;
148 refvar
&= ~ALTERA_TSE_CMD_ETH_SPEED_MSK
;
149 refvar
|= ALTERA_TSE_CMD_ENA_10_MSK
;
152 writel(refvar
, &mac_dev
->command_config
);
155 static int altera_tse_send(struct udevice
*dev
, void *packet
, int length
)
157 struct altera_tse_priv
*priv
= dev_get_priv(dev
);
158 struct alt_sgdma_descriptor
*tx_desc
= priv
->tx_desc
;
159 unsigned long tx_buf
= (unsigned long)packet
;
161 flush_dcache_range(tx_buf
, tx_buf
+ length
);
162 alt_sgdma_construct_descriptor(
165 packet
, /* read addr */
166 NULL
, /* write addr */
167 length
, /* length or EOP ,will change for each tx */
170 1 /* write fixed or sop */
173 /* send the packet */
174 alt_sgdma_start_transfer(priv
->sgdma_tx
, tx_desc
);
175 alt_sgdma_wait_transfer(priv
->sgdma_tx
);
176 debug("sent %d bytes\n", tx_desc
->actual_bytes_transferred
);
178 return tx_desc
->actual_bytes_transferred
;
181 static int altera_tse_recv(struct udevice
*dev
, int flags
, uchar
**packetp
)
183 struct altera_tse_priv
*priv
= dev_get_priv(dev
);
184 struct alt_sgdma_descriptor
*rx_desc
= priv
->rx_desc
;
187 if (rx_desc
->descriptor_status
&
188 ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK
) {
189 packet_length
= rx_desc
->actual_bytes_transferred
;
190 debug("recv %d bytes\n", packet_length
);
191 *packetp
= priv
->rx_buf
;
193 return packet_length
;
199 static int altera_tse_free_pkt(struct udevice
*dev
, uchar
*packet
,
202 struct altera_tse_priv
*priv
= dev_get_priv(dev
);
203 struct alt_sgdma_descriptor
*rx_desc
= priv
->rx_desc
;
204 unsigned long rx_buf
= (unsigned long)priv
->rx_buf
;
206 alt_sgdma_wait_transfer(priv
->sgdma_rx
);
207 invalidate_dcache_range(rx_buf
, rx_buf
+ PKTSIZE_ALIGN
);
208 alt_sgdma_construct_descriptor(
211 NULL
, /* read addr */
212 priv
->rx_buf
, /* write addr */
213 0, /* length or EOP */
216 0 /* write fixed or sop */
219 /* setup the sgdma */
220 alt_sgdma_start_transfer(priv
->sgdma_rx
, rx_desc
);
221 debug("recv setup\n");
226 static void altera_tse_stop(struct udevice
*dev
)
228 struct altera_tse_priv
*priv
= dev_get_priv(dev
);
229 struct alt_tse_mac
*mac_dev
= priv
->mac_dev
;
230 struct alt_sgdma_registers
*rx_sgdma
= priv
->sgdma_rx
;
231 struct alt_sgdma_registers
*tx_sgdma
= priv
->sgdma_tx
;
232 struct alt_sgdma_descriptor
*rx_desc
= priv
->rx_desc
;
237 /* clear rx desc & wait for sgdma to complete */
238 rx_desc
->descriptor_control
= 0;
239 writel(0, &rx_sgdma
->control
);
240 ret
= alt_sgdma_wait_transfer(rx_sgdma
);
241 if (ret
== -ETIMEDOUT
)
242 writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK
,
245 writel(0, &tx_sgdma
->control
);
246 ret
= alt_sgdma_wait_transfer(tx_sgdma
);
247 if (ret
== -ETIMEDOUT
)
248 writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK
,
252 writel(ALTERA_TSE_CMD_SW_RESET_MSK
, &mac_dev
->command_config
);
253 ctime
= get_timer(0);
255 status
= readl(&mac_dev
->command_config
);
256 if (!(status
& ALTERA_TSE_CMD_SW_RESET_MSK
))
258 if (get_timer(ctime
) > ALT_TSE_SW_RESET_TIMEOUT
) {
259 debug("Reset mac timeout\n");
265 static int tse_mdio_read(struct mii_dev
*bus
, int addr
, int devad
, int reg
)
267 struct altera_tse_priv
*priv
= bus
->priv
;
268 struct alt_tse_mac
*mac_dev
= priv
->mac_dev
;
271 /* set mdio address */
272 writel(addr
, &mac_dev
->mdio_phy1_addr
);
274 value
= readl(&mac_dev
->mdio_phy1
[reg
]);
276 return value
& 0xffff;
279 static int tse_mdio_write(struct mii_dev
*bus
, int addr
, int devad
, int reg
,
282 struct altera_tse_priv
*priv
= bus
->priv
;
283 struct alt_tse_mac
*mac_dev
= priv
->mac_dev
;
285 /* set mdio address */
286 writel(addr
, &mac_dev
->mdio_phy1_addr
);
288 writel(val
, &mac_dev
->mdio_phy1
[reg
]);
293 static int tse_mdio_init(const char *name
, struct altera_tse_priv
*priv
)
295 struct mii_dev
*bus
= mdio_alloc();
298 printf("Failed to allocate MDIO bus\n");
302 bus
->read
= tse_mdio_read
;
303 bus
->write
= tse_mdio_write
;
304 snprintf(bus
->name
, sizeof(bus
->name
), name
);
306 bus
->priv
= (void *)priv
;
308 return mdio_register(bus
);
311 static int tse_phy_init(struct altera_tse_priv
*priv
, void *dev
)
313 struct phy_device
*phydev
;
314 unsigned int mask
= 0xffffffff;
317 mask
= 1 << priv
->phyaddr
;
319 phydev
= phy_find_by_mask(priv
->bus
, mask
, priv
->interface
);
323 phy_connect_dev(phydev
, dev
);
325 phydev
->supported
&= PHY_GBIT_FEATURES
;
326 phydev
->advertising
= phydev
->supported
;
328 priv
->phydev
= phydev
;
334 static int altera_tse_write_hwaddr(struct udevice
*dev
)
336 struct altera_tse_priv
*priv
= dev_get_priv(dev
);
337 struct alt_tse_mac
*mac_dev
= priv
->mac_dev
;
338 struct eth_pdata
*pdata
= dev_get_platdata(dev
);
339 u8
*hwaddr
= pdata
->enetaddr
;
342 mac_lo
= (hwaddr
[3] << 24) | (hwaddr
[2] << 16) |
343 (hwaddr
[1] << 8) | hwaddr
[0];
344 mac_hi
= (hwaddr
[5] << 8) | hwaddr
[4];
345 debug("Set MAC address to 0x%04x%08x\n", mac_hi
, mac_lo
);
347 writel(mac_lo
, &mac_dev
->mac_addr_0
);
348 writel(mac_hi
, &mac_dev
->mac_addr_1
);
349 writel(mac_lo
, &mac_dev
->supp_mac_addr_0_0
);
350 writel(mac_hi
, &mac_dev
->supp_mac_addr_0_1
);
351 writel(mac_lo
, &mac_dev
->supp_mac_addr_1_0
);
352 writel(mac_hi
, &mac_dev
->supp_mac_addr_1_1
);
353 writel(mac_lo
, &mac_dev
->supp_mac_addr_2_0
);
354 writel(mac_hi
, &mac_dev
->supp_mac_addr_2_1
);
355 writel(mac_lo
, &mac_dev
->supp_mac_addr_3_0
);
356 writel(mac_hi
, &mac_dev
->supp_mac_addr_3_1
);
361 static int altera_tse_start(struct udevice
*dev
)
363 struct altera_tse_priv
*priv
= dev_get_priv(dev
);
364 struct alt_tse_mac
*mac_dev
= priv
->mac_dev
;
368 /* need to create sgdma */
369 debug("Configuring rx desc\n");
370 altera_tse_free_pkt(dev
, priv
->rx_buf
, PKTSIZE_ALIGN
);
372 debug("Configuring TSE Mac\n");
373 /* Initialize MAC registers */
374 writel(PKTSIZE_ALIGN
, &mac_dev
->max_frame_length
);
375 writel(priv
->rx_fifo_depth
- 16, &mac_dev
->rx_sel_empty_threshold
);
376 writel(0, &mac_dev
->rx_sel_full_threshold
);
377 writel(priv
->tx_fifo_depth
- 16, &mac_dev
->tx_sel_empty_threshold
);
378 writel(0, &mac_dev
->tx_sel_full_threshold
);
379 writel(8, &mac_dev
->rx_almost_empty_threshold
);
380 writel(8, &mac_dev
->rx_almost_full_threshold
);
381 writel(8, &mac_dev
->tx_almost_empty_threshold
);
382 writel(3, &mac_dev
->tx_almost_full_threshold
);
385 writel(0, &mac_dev
->rx_cmd_stat
);
386 writel(0, &mac_dev
->tx_cmd_stat
);
389 val
= ALTERA_TSE_CMD_TX_ENA_MSK
| ALTERA_TSE_CMD_RX_ENA_MSK
;
390 writel(val
, &mac_dev
->command_config
);
392 /* Start up the PHY */
393 ret
= phy_startup(priv
->phydev
);
395 debug("Could not initialize PHY %s\n",
396 priv
->phydev
->dev
->name
);
400 tse_adjust_link(priv
, priv
->phydev
);
402 if (!priv
->phydev
->link
)
408 static int altera_tse_probe(struct udevice
*dev
)
410 struct eth_pdata
*pdata
= dev_get_platdata(dev
);
411 struct altera_tse_priv
*priv
= dev_get_priv(dev
);
412 const void *blob
= gd
->fdt_blob
;
413 int node
= dev
->of_offset
;
414 const char *list
, *end
;
416 void *base
, *desc_mem
= NULL
;
417 unsigned long addr
, size
;
422 * decode regs, assume address-cells and size-cells are both one.
423 * there are multiple reg tuples, and they need to match with
426 list
= fdt_getprop(blob
, node
, "reg-names", &len
);
430 cell
= fdt_getprop(blob
, node
, "reg", &len
);
435 addr
= fdt_translate_address((void *)blob
,
437 size
= fdt_addr_to_cpu(cell
[idx
+ 1]);
438 base
= ioremap(addr
, size
);
440 if (strcmp(list
, "control_port") == 0)
441 priv
->mac_dev
= base
;
442 else if (strcmp(list
, "rx_csr") == 0)
443 priv
->sgdma_rx
= base
;
444 else if (strcmp(list
, "tx_csr") == 0)
445 priv
->sgdma_tx
= base
;
446 else if (strcmp(list
, "s1") == 0)
451 /* decode fifo depth */
452 priv
->rx_fifo_depth
= fdtdec_get_int(blob
, node
,
454 priv
->tx_fifo_depth
= fdtdec_get_int(blob
, node
,
457 addr
= fdtdec_get_int(blob
, node
,
459 addr
= fdt_node_offset_by_phandle(blob
, addr
);
460 priv
->phyaddr
= fdtdec_get_int(blob
, addr
,
463 len
= sizeof(struct alt_sgdma_descriptor
) * 4;
465 desc_mem
= dma_alloc_coherent(len
, &addr
);
469 memset(desc_mem
, 0, len
);
470 priv
->tx_desc
= desc_mem
;
471 priv
->rx_desc
= priv
->tx_desc
+ 2;
472 /* allocate recv packet buffer */
473 priv
->rx_buf
= malloc_cache_aligned(PKTSIZE_ALIGN
);
477 /* stop controller */
478 debug("Reset TSE & SGDMAs\n");
479 altera_tse_stop(dev
);
482 priv
->interface
= pdata
->phy_interface
;
483 tse_mdio_init(dev
->name
, priv
);
484 priv
->bus
= miiphy_get_dev_by_name(dev
->name
);
486 ret
= tse_phy_init(priv
, dev
);
491 static int altera_tse_ofdata_to_platdata(struct udevice
*dev
)
493 struct eth_pdata
*pdata
= dev_get_platdata(dev
);
494 const char *phy_mode
;
496 pdata
->phy_interface
= -1;
497 phy_mode
= fdt_getprop(gd
->fdt_blob
, dev
->of_offset
, "phy-mode", NULL
);
499 pdata
->phy_interface
= phy_get_interface_by_name(phy_mode
);
500 if (pdata
->phy_interface
== -1) {
501 debug("%s: Invalid PHY interface '%s'\n", __func__
, phy_mode
);
508 static const struct eth_ops altera_tse_ops
= {
509 .start
= altera_tse_start
,
510 .send
= altera_tse_send
,
511 .recv
= altera_tse_recv
,
512 .free_pkt
= altera_tse_free_pkt
,
513 .stop
= altera_tse_stop
,
514 .write_hwaddr
= altera_tse_write_hwaddr
,
517 static const struct udevice_id altera_tse_ids
[] = {
518 { .compatible
= "altr,tse-1.0", },
522 U_BOOT_DRIVER(altera_tse
) = {
523 .name
= "altera_tse",
525 .of_match
= altera_tse_ids
,
526 .ops
= &altera_tse_ops
,
527 .ofdata_to_platdata
= altera_tse_ofdata_to_platdata
,
528 .platdata_auto_alloc_size
= sizeof(struct eth_pdata
),
529 .priv_auto_alloc_size
= sizeof(struct altera_tse_priv
),
530 .probe
= altera_tse_probe
,