2 * Xilinx xps_ll_temac ethernet driver for u-boot
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 * CREDITS: tsec driver
16 * This program is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License as published by the
18 * Free Software Foundation; either version 2 of the License, or (at your
19 * option) any later version.
21 * [0]: http://www.xilinx.com/support/documentation
23 * [M]: [0]/ip_documentation/mpmc.pdf
24 * [S]: [0]/ip_documentation/xps_ll_temac.pdf
25 * [A]: [0]/application_notes/xapp1041.pdf
32 #include <asm/types.h>
35 #include "xilinx_ll_temac.h"
36 #include "xilinx_ll_temac_sdma.h"
40 static unsigned int rx_idx
; /* index of the current RX buffer */
41 static unsigned int tx_idx
; /* index of the current TX buffer */
44 struct cdmac_bd rx
[PKTBUFSRX
];
45 struct cdmac_bd tx
[TX_BUF_CNT
];
49 * DMA Buffer Descriptor alignment
51 * If the address contained in the Next Descriptor Pointer register is not
52 * 8-word aligned or reaches beyond the range of available memory, the SDMA
53 * halts processing and sets the CDMAC_BD_STCTRL_ERROR bit in the respective
54 * status register (tx_chnl_sts or rx_chnl_sts).
56 * [1]: [0]/ip_documentation/mpmc.pdf
57 * page 161, Next Descriptor Pointer
59 static struct rtx_cdmac_bd cdmac_bd
__aligned(32);
61 #if defined(CONFIG_XILINX_440) || defined(CONFIG_XILINX_405)
64 * Indirect DCR access operations mi{ft}dcr_xilinx() espacialy
65 * for Xilinx PowerPC implementations on FPGA.
67 * FIXME: This part should go up to arch/powerpc -- but where?
69 #include <asm/processor.h>
70 #define XILINX_INDIRECT_DCR_ADDRESS_REG 0
71 #define XILINX_INDIRECT_DCR_ACCESS_REG 1
72 inline unsigned mifdcr_xilinx(const unsigned dcrn
)
74 mtdcr(XILINX_INDIRECT_DCR_ADDRESS_REG
, dcrn
);
75 return mfdcr(XILINX_INDIRECT_DCR_ACCESS_REG
);
77 inline void mitdcr_xilinx(const unsigned dcrn
, int val
)
79 mtdcr(XILINX_INDIRECT_DCR_ADDRESS_REG
, dcrn
);
80 mtdcr(XILINX_INDIRECT_DCR_ACCESS_REG
, val
);
83 /* Xilinx Device Control Register (DCR) in/out accessors */
84 inline unsigned ll_temac_xldcr_in32(phys_addr_t addr
)
86 return mifdcr_xilinx((const unsigned)addr
);
88 inline void ll_temac_xldcr_out32(phys_addr_t addr
, unsigned value
)
90 mitdcr_xilinx((const unsigned)addr
, value
);
93 void ll_temac_collect_xldcr_sdma_reg_addr(struct eth_device
*dev
)
95 struct ll_temac
*ll_temac
= dev
->priv
;
96 phys_addr_t dmac_ctrl
= ll_temac
->ctrladdr
;
97 phys_addr_t
*ra
= ll_temac
->sdma_reg_addr
;
99 ra
[TX_NXTDESC_PTR
] = dmac_ctrl
+ TX_NXTDESC_PTR
;
100 ra
[TX_CURBUF_ADDR
] = dmac_ctrl
+ TX_CURBUF_ADDR
;
101 ra
[TX_CURBUF_LENGTH
] = dmac_ctrl
+ TX_CURBUF_LENGTH
;
102 ra
[TX_CURDESC_PTR
] = dmac_ctrl
+ TX_CURDESC_PTR
;
103 ra
[TX_TAILDESC_PTR
] = dmac_ctrl
+ TX_TAILDESC_PTR
;
104 ra
[TX_CHNL_CTRL
] = dmac_ctrl
+ TX_CHNL_CTRL
;
105 ra
[TX_IRQ_REG
] = dmac_ctrl
+ TX_IRQ_REG
;
106 ra
[TX_CHNL_STS
] = dmac_ctrl
+ TX_CHNL_STS
;
107 ra
[RX_NXTDESC_PTR
] = dmac_ctrl
+ RX_NXTDESC_PTR
;
108 ra
[RX_CURBUF_ADDR
] = dmac_ctrl
+ RX_CURBUF_ADDR
;
109 ra
[RX_CURBUF_LENGTH
] = dmac_ctrl
+ RX_CURBUF_LENGTH
;
110 ra
[RX_CURDESC_PTR
] = dmac_ctrl
+ RX_CURDESC_PTR
;
111 ra
[RX_TAILDESC_PTR
] = dmac_ctrl
+ RX_TAILDESC_PTR
;
112 ra
[RX_CHNL_CTRL
] = dmac_ctrl
+ RX_CHNL_CTRL
;
113 ra
[RX_IRQ_REG
] = dmac_ctrl
+ RX_IRQ_REG
;
114 ra
[RX_CHNL_STS
] = dmac_ctrl
+ RX_CHNL_STS
;
115 ra
[DMA_CONTROL_REG
] = dmac_ctrl
+ DMA_CONTROL_REG
;
118 #endif /* CONFIG_XILINX_440 || ONFIG_XILINX_405 */
120 /* Xilinx Processor Local Bus (PLB) in/out accessors */
121 inline unsigned ll_temac_xlplb_in32(phys_addr_t addr
)
123 return in_be32((void *)addr
);
125 inline void ll_temac_xlplb_out32(phys_addr_t addr
, unsigned value
)
127 out_be32((void *)addr
, value
);
130 /* collect all register addresses for Xilinx PLB in/out accessors */
131 void ll_temac_collect_xlplb_sdma_reg_addr(struct eth_device
*dev
)
133 struct ll_temac
*ll_temac
= dev
->priv
;
134 struct sdma_ctrl
*sdma_ctrl
= (void *)ll_temac
->ctrladdr
;
135 phys_addr_t
*ra
= ll_temac
->sdma_reg_addr
;
137 ra
[TX_NXTDESC_PTR
] = (phys_addr_t
)&sdma_ctrl
->tx_nxtdesc_ptr
;
138 ra
[TX_CURBUF_ADDR
] = (phys_addr_t
)&sdma_ctrl
->tx_curbuf_addr
;
139 ra
[TX_CURBUF_LENGTH
] = (phys_addr_t
)&sdma_ctrl
->tx_curbuf_length
;
140 ra
[TX_CURDESC_PTR
] = (phys_addr_t
)&sdma_ctrl
->tx_curdesc_ptr
;
141 ra
[TX_TAILDESC_PTR
] = (phys_addr_t
)&sdma_ctrl
->tx_taildesc_ptr
;
142 ra
[TX_CHNL_CTRL
] = (phys_addr_t
)&sdma_ctrl
->tx_chnl_ctrl
;
143 ra
[TX_IRQ_REG
] = (phys_addr_t
)&sdma_ctrl
->tx_irq_reg
;
144 ra
[TX_CHNL_STS
] = (phys_addr_t
)&sdma_ctrl
->tx_chnl_sts
;
145 ra
[RX_NXTDESC_PTR
] = (phys_addr_t
)&sdma_ctrl
->rx_nxtdesc_ptr
;
146 ra
[RX_CURBUF_ADDR
] = (phys_addr_t
)&sdma_ctrl
->rx_curbuf_addr
;
147 ra
[RX_CURBUF_LENGTH
] = (phys_addr_t
)&sdma_ctrl
->rx_curbuf_length
;
148 ra
[RX_CURDESC_PTR
] = (phys_addr_t
)&sdma_ctrl
->rx_curdesc_ptr
;
149 ra
[RX_TAILDESC_PTR
] = (phys_addr_t
)&sdma_ctrl
->rx_taildesc_ptr
;
150 ra
[RX_CHNL_CTRL
] = (phys_addr_t
)&sdma_ctrl
->rx_chnl_ctrl
;
151 ra
[RX_IRQ_REG
] = (phys_addr_t
)&sdma_ctrl
->rx_irq_reg
;
152 ra
[RX_CHNL_STS
] = (phys_addr_t
)&sdma_ctrl
->rx_chnl_sts
;
153 ra
[DMA_CONTROL_REG
] = (phys_addr_t
)&sdma_ctrl
->dma_control_reg
;
156 /* Check for TX and RX channel errors. */
157 static inline int ll_temac_sdma_error(struct eth_device
*dev
)
160 struct ll_temac
*ll_temac
= dev
->priv
;
161 phys_addr_t
*ra
= ll_temac
->sdma_reg_addr
;
163 err
= ll_temac
->in32(ra
[TX_CHNL_STS
]) & CHNL_STS_ERROR
;
164 err
|= ll_temac
->in32(ra
[RX_CHNL_STS
]) & CHNL_STS_ERROR
;
169 int ll_temac_init_sdma(struct eth_device
*dev
)
171 struct ll_temac
*ll_temac
= dev
->priv
;
172 struct cdmac_bd
*rx_dp
;
173 struct cdmac_bd
*tx_dp
;
174 phys_addr_t
*ra
= ll_temac
->sdma_reg_addr
;
177 printf("%s: SDMA: %d Rx buffers, %d Tx buffers\n",
178 dev
->name
, PKTBUFSRX
, TX_BUF_CNT
);
180 /* Initialize the Rx Buffer descriptors */
181 for (i
= 0; i
< PKTBUFSRX
; i
++) {
182 rx_dp
= &cdmac_bd
.rx
[i
];
183 memset(rx_dp
, 0, sizeof(*rx_dp
));
184 rx_dp
->next_p
= rx_dp
;
185 rx_dp
->buf_len
= PKTSIZE_ALIGN
;
186 rx_dp
->phys_buf_p
= (u8
*)NetRxPackets
[i
];
187 flush_cache((u32
)rx_dp
->phys_buf_p
, PKTSIZE_ALIGN
);
189 flush_cache((u32
)cdmac_bd
.rx
, sizeof(cdmac_bd
.rx
));
191 /* Initialize the TX Buffer Descriptors */
192 for (i
= 0; i
< TX_BUF_CNT
; i
++) {
193 tx_dp
= &cdmac_bd
.tx
[i
];
194 memset(tx_dp
, 0, sizeof(*tx_dp
));
195 tx_dp
->next_p
= tx_dp
;
197 flush_cache((u32
)cdmac_bd
.tx
, sizeof(cdmac_bd
.tx
));
199 /* Reset index counter to the Rx and Tx Buffer descriptors */
202 /* initial Rx DMA start by writing to respective TAILDESC_PTR */
203 ll_temac
->out32(ra
[RX_CURDESC_PTR
], (int)&cdmac_bd
.rx
[rx_idx
]);
204 ll_temac
->out32(ra
[RX_TAILDESC_PTR
], (int)&cdmac_bd
.rx
[rx_idx
]);
209 int ll_temac_halt_sdma(struct eth_device
*dev
)
211 unsigned timeout
= 50; /* 1usec * 50 = 50usec */
212 struct ll_temac
*ll_temac
= dev
->priv
;
213 phys_addr_t
*ra
= ll_temac
->sdma_reg_addr
;
218 * Quote from MPMC documentation: Writing a 1 to this field
219 * forces the DMA engine to shutdown and reset itself. After
220 * setting this bit, software must poll it until the bit is
221 * cleared by the DMA. This indicates that the reset process
222 * is done and the pipeline has been flushed.
224 ll_temac
->out32(ra
[DMA_CONTROL_REG
], DMA_CONTROL_RESET
);
225 while (timeout
&& (ll_temac
->in32(ra
[DMA_CONTROL_REG
])
226 & DMA_CONTROL_RESET
)) {
232 printf("%s: Timeout\n", __func__
);
239 int ll_temac_reset_sdma(struct eth_device
*dev
)
242 struct ll_temac
*ll_temac
= dev
->priv
;
243 phys_addr_t
*ra
= ll_temac
->sdma_reg_addr
;
245 /* Soft reset the DMA. */
246 if (ll_temac_halt_sdma(dev
))
249 /* Now clear the interrupts. */
250 r
= ll_temac
->in32(ra
[TX_CHNL_CTRL
]);
251 r
&= ~CHNL_CTRL_IRQ_MASK
;
252 ll_temac
->out32(ra
[TX_CHNL_CTRL
], r
);
254 r
= ll_temac
->in32(ra
[RX_CHNL_CTRL
]);
255 r
&= ~CHNL_CTRL_IRQ_MASK
;
256 ll_temac
->out32(ra
[RX_CHNL_CTRL
], r
);
258 /* Now ACK pending IRQs. */
259 ll_temac
->out32(ra
[TX_IRQ_REG
], IRQ_REG_IRQ_MASK
);
260 ll_temac
->out32(ra
[RX_IRQ_REG
], IRQ_REG_IRQ_MASK
);
262 /* Set tail-ptr mode, disable errors for both channels. */
263 ll_temac
->out32(ra
[DMA_CONTROL_REG
],
264 /* Enable use of tail pointer register */
266 /* Disable error when 2 or 4 bit coalesce cnt overfl */
267 DMA_CONTROL_RXOCEID
|
268 /* Disable error when 2 or 4 bit coalesce cnt overfl */
269 DMA_CONTROL_TXOCEID
);
274 int ll_temac_recv_sdma(struct eth_device
*dev
)
277 struct cdmac_bd
*rx_dp
= &cdmac_bd
.rx
[rx_idx
];
278 struct ll_temac
*ll_temac
= dev
->priv
;
279 phys_addr_t
*ra
= ll_temac
->sdma_reg_addr
;
281 if (ll_temac_sdma_error(dev
)) {
283 if (ll_temac_reset_sdma(dev
))
286 ll_temac_init_sdma(dev
);
289 flush_cache((u32
)rx_dp
, sizeof(*rx_dp
));
291 if (!(rx_dp
->sca
.stctrl
& CDMAC_BD_STCTRL_COMPLETED
))
294 if (rx_dp
->sca
.stctrl
& (CDMAC_BD_STCTRL_SOP
| CDMAC_BD_STCTRL_EOP
)) {
296 length
= rx_dp
->sca
.app
[4] & CDMAC_BD_APP4_RXBYTECNT_MASK
;
300 printf("%s: Got part of package, unsupported (%x)\n",
301 __func__
, rx_dp
->sca
.stctrl
);
304 /* flip the buffer */
305 flush_cache((u32
)rx_dp
->phys_buf_p
, length
);
307 /* reset the current descriptor */
308 rx_dp
->sca
.stctrl
= 0;
309 rx_dp
->sca
.app
[4] = 0;
310 flush_cache((u32
)rx_dp
, sizeof(*rx_dp
));
312 /* Find next empty buffer descriptor, preparation for next iteration */
313 rx_idx
= (rx_idx
+ 1) % PKTBUFSRX
;
314 rx_dp
= &cdmac_bd
.rx
[rx_idx
];
315 flush_cache((u32
)rx_dp
, sizeof(*rx_dp
));
317 /* DMA start by writing to respective TAILDESC_PTR */
318 ll_temac
->out32(ra
[RX_CURDESC_PTR
], (int)&cdmac_bd
.rx
[rx_idx
]);
319 ll_temac
->out32(ra
[RX_TAILDESC_PTR
], (int)&cdmac_bd
.rx
[rx_idx
]);
321 if (length
> 0 && pb_idx
!= -1)
322 NetReceive(NetRxPackets
[pb_idx
], length
);
327 int ll_temac_send_sdma(struct eth_device
*dev
, volatile void *packet
,
330 unsigned timeout
= 50; /* 1usec * 50 = 50usec */
331 struct cdmac_bd
*tx_dp
= &cdmac_bd
.tx
[tx_idx
];
332 struct ll_temac
*ll_temac
= dev
->priv
;
333 phys_addr_t
*ra
= ll_temac
->sdma_reg_addr
;
335 if (ll_temac_sdma_error(dev
)) {
337 if (ll_temac_reset_sdma(dev
))
340 ll_temac_init_sdma(dev
);
343 tx_dp
->phys_buf_p
= (u8
*)packet
;
344 tx_dp
->buf_len
= length
;
345 tx_dp
->sca
.stctrl
= CDMAC_BD_STCTRL_SOP
| CDMAC_BD_STCTRL_EOP
|
346 CDMAC_BD_STCTRL_STOP_ON_END
;
348 flush_cache((u32
)packet
, length
);
349 flush_cache((u32
)tx_dp
, sizeof(*tx_dp
));
351 /* DMA start by writing to respective TAILDESC_PTR */
352 ll_temac
->out32(ra
[TX_CURDESC_PTR
], (int)tx_dp
);
353 ll_temac
->out32(ra
[TX_TAILDESC_PTR
], (int)tx_dp
);
355 /* Find next empty buffer descriptor, preparation for next iteration */
356 tx_idx
= (tx_idx
+ 1) % TX_BUF_CNT
;
357 tx_dp
= &cdmac_bd
.tx
[tx_idx
];
360 flush_cache((u32
)tx_dp
, sizeof(*tx_dp
));
362 } while (timeout
-- && !(tx_dp
->sca
.stctrl
& CDMAC_BD_STCTRL_COMPLETED
));
365 printf("%s: Timeout\n", __func__
);