]>
Commit | Line | Data |
---|---|---|
df482650 SL |
1 | /* |
2 | * Xilinx xps_ll_temac ethernet driver for u-boot | |
3 | * | |
4 | * SDMA sub-controller interface | |
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 | * | |
1a459660 | 14 | * SPDX-License-Identifier: GPL-2.0+ |
df482650 SL |
15 | * |
16 | * [0]: http://www.xilinx.com/support/documentation | |
17 | * | |
18 | * [S]: [0]/ip_documentation/xps_ll_temac.pdf | |
19 | * [A]: [0]/application_notes/xapp1041.pdf | |
20 | */ | |
21 | #ifndef _XILINX_LL_TEMAC_SDMA_ | |
22 | #define _XILINX_LL_TEMAC_SDMA_ | |
23 | ||
24 | #include <net.h> | |
25 | ||
26 | #include <asm/types.h> | |
27 | #include <asm/byteorder.h> | |
28 | ||
29 | #include <linux/compiler.h> | |
30 | ||
31 | #if !defined(__BIG_ENDIAN) | |
32 | # error LL_TEMAC requires big endianess | |
33 | #endif | |
34 | ||
35 | /* | |
36 | * DMA Buffer Descriptor for CDMAC | |
37 | * | |
38 | * Used for data connection from and to (Rx/Tx) the LocalLink (LL) TEMAC via | |
39 | * the Communications Direct Memory Access Controller (CDMAC) -- one for each. | |
40 | * | |
41 | * overview: | |
42 | * ftp://ftp.xilinx.com/pub/documentation/misc/mpmc_getting_started.pdf | |
43 | * | |
44 | * [1]: [0]/ip_documentation/mpmc.pdf | |
45 | * page 140, DMA Operation Descriptors | |
46 | * | |
47 | * [2]: [0]/user_guides/ug200.pdf | |
48 | * page 229, DMA Controller -- Descriptor Format | |
49 | * | |
50 | * [3]: [0]/ip_documentation/xps_ll_temac.pdf | |
51 | * page 72, Transmit LocalLink Frame Format | |
52 | * page 73, Receive LocalLink Frame Format | |
53 | */ | |
54 | struct cdmac_bd { | |
55 | struct cdmac_bd *next_p; /* Next Descriptor Pointer */ | |
56 | u8 *phys_buf_p; /* Buffer Address */ | |
57 | u32 buf_len; /* Buffer Length */ | |
58 | union { | |
59 | u8 stctrl; /* Status/Control the DMA transfer */ | |
60 | u32 app[5]; /* application specific data */ | |
61 | } __packed __aligned(1) sca; | |
62 | }; | |
63 | ||
64 | /* CDMAC Descriptor Status and Control (stctrl), [1] p140, [2] p230 */ | |
65 | #define CDMAC_BD_STCTRL_ERROR (1 << 7) | |
66 | #define CDMAC_BD_STCTRL_IRQ_ON_END (1 << 6) | |
67 | #define CDMAC_BD_STCTRL_STOP_ON_END (1 << 5) | |
68 | #define CDMAC_BD_STCTRL_COMPLETED (1 << 4) | |
69 | #define CDMAC_BD_STCTRL_SOP (1 << 3) | |
70 | #define CDMAC_BD_STCTRL_EOP (1 << 2) | |
71 | #define CDMAC_BD_STCTRL_DMACHBUSY (1 << 1) | |
72 | ||
73 | /* CDMAC Descriptor APP0: Transmit LocalLink Footer Word 3, [3] p72 */ | |
74 | #define CDMAC_BD_APP0_TXCSCNTRL (1 << 0) | |
75 | ||
76 | /* CDMAC Descriptor APP1: Transmit LocalLink Footer Word 4, [3] p73 */ | |
77 | #define CDMAC_BD_APP1_TXCSBEGIN_POS 16 | |
78 | #define CDMAC_BD_APP1_TXCSBEGIN_MASK (0xFFFF << CDMAC_BD_APP1_TXCSBEGIN_POS) | |
79 | #define CDMAC_BD_APP1_TXCSINSERT_POS 0 | |
80 | #define CDMAC_BD_APP1_TXCSINSERT_MASK (0xFFFF << CDMAC_BD_APP1_TXCSINSERT_POS) | |
81 | ||
82 | /* CDMAC Descriptor APP2: Transmit LocalLink Footer Word 5, [3] p73 */ | |
83 | #define CDMAC_BD_APP2_TXCSINIT_POS 0 | |
84 | #define CDMAC_BD_APP2_TXCSINIT_MASK (0xFFFF << CDMAC_BD_APP2_TXCSINIT_POS) | |
85 | ||
86 | /* CDMAC Descriptor APP0: Receive LocalLink Footer Word 3, [3] p73 */ | |
87 | #define CDMAC_BD_APP0_MADDRU_POS 0 | |
88 | #define CDMAC_BD_APP0_MADDRU_MASK (0xFFFF << CDMAC_BD_APP0_MADDRU_POS) | |
89 | ||
90 | /* CDMAC Descriptor APP1: Receive LocalLink Footer Word 4, [3] p74 */ | |
91 | #define CDMAC_BD_APP1_MADDRL_POS 0 | |
92 | #define CDMAC_BD_APP1_MADDRL_MASK (~0UL << CDMAC_BD_APP1_MADDRL_POS) | |
93 | ||
94 | /* CDMAC Descriptor APP2: Receive LocalLink Footer Word 5, [3] p74 */ | |
95 | #define CDMAC_BD_APP2_BCAST_FRAME (1 << 2) | |
96 | #define CDMAC_BD_APP2_IPC_MCAST_FRAME (1 << 1) | |
97 | #define CDMAC_BD_APP2_MAC_MCAST_FRAME (1 << 0) | |
98 | ||
99 | /* CDMAC Descriptor APP3: Receive LocalLink Footer Word 6, [3] p74 */ | |
100 | #define CDMAC_BD_APP3_TLTPID_POS 16 | |
101 | #define CDMAC_BD_APP3_TLTPID_MASK (0xFFFF << CDMAC_BD_APP3_TLTPID_POS) | |
102 | #define CDMAC_BD_APP3_RXCSRAW_POS 0 | |
103 | #define CDMAC_BD_APP3_RXCSRAW_MASK (0xFFFF << CDMAC_BD_APP3_RXCSRAW_POS) | |
104 | ||
105 | /* CDMAC Descriptor APP4: Receive LocalLink Footer Word 7, [3] p74 */ | |
106 | #define CDMAC_BD_APP4_VLANTAG_POS 16 | |
107 | #define CDMAC_BD_APP4_VLANTAG_MASK (0xFFFF << CDMAC_BD_APP4_VLANTAG_POS) | |
108 | #define CDMAC_BD_APP4_RXBYTECNT_POS 0 | |
109 | #define CDMAC_BD_APP4_RXBYTECNT_MASK (0x3FFF << CDMAC_BD_APP4_RXBYTECNT_POS) | |
110 | ||
111 | /* | |
112 | * SDMA Register Definition | |
113 | * | |
114 | * [0]: http://www.xilinx.com/support/documentation | |
115 | * | |
116 | * [1]: [0]/ip_documentation/mpmc.pdf | |
117 | * page 54, SDMA Register Summary | |
118 | * page 160, SDMA Registers | |
119 | * | |
120 | * [2]: [0]/user_guides/ug200.pdf | |
121 | * page 244, DMA Controller -- Programming Interface and Registers | |
122 | */ | |
123 | #define SDMA_CTRL_REGTYPE u32 | |
124 | #define SDMA_CTRL_REGSIZE sizeof(SDMA_CTRL_REGTYPE) | |
125 | struct sdma_ctrl { | |
126 | /* Transmit Registers */ | |
127 | SDMA_CTRL_REGTYPE tx_nxtdesc_ptr; /* TX Next Description Pointer */ | |
128 | SDMA_CTRL_REGTYPE tx_curbuf_addr; /* TX Current Buffer Address */ | |
129 | SDMA_CTRL_REGTYPE tx_curbuf_length; /* TX Current Buffer Length */ | |
130 | SDMA_CTRL_REGTYPE tx_curdesc_ptr; /* TX Current Descriptor Pointer */ | |
131 | SDMA_CTRL_REGTYPE tx_taildesc_ptr; /* TX Tail Descriptor Pointer */ | |
132 | SDMA_CTRL_REGTYPE tx_chnl_ctrl; /* TX Channel Control */ | |
133 | SDMA_CTRL_REGTYPE tx_irq_reg; /* TX Interrupt Register */ | |
134 | SDMA_CTRL_REGTYPE tx_chnl_sts; /* TX Status Register */ | |
135 | /* Receive Registers */ | |
136 | SDMA_CTRL_REGTYPE rx_nxtdesc_ptr; /* RX Next Descriptor Pointer */ | |
137 | SDMA_CTRL_REGTYPE rx_curbuf_addr; /* RX Current Buffer Address */ | |
138 | SDMA_CTRL_REGTYPE rx_curbuf_length; /* RX Current Buffer Length */ | |
139 | SDMA_CTRL_REGTYPE rx_curdesc_ptr; /* RX Current Descriptor Pointer */ | |
140 | SDMA_CTRL_REGTYPE rx_taildesc_ptr; /* RX Tail Descriptor Pointer */ | |
141 | SDMA_CTRL_REGTYPE rx_chnl_ctrl; /* RX Channel Control */ | |
142 | SDMA_CTRL_REGTYPE rx_irq_reg; /* RX Interrupt Register */ | |
143 | SDMA_CTRL_REGTYPE rx_chnl_sts; /* RX Status Register */ | |
144 | /* Control Registers */ | |
145 | SDMA_CTRL_REGTYPE dma_control_reg; /* DMA Control Register */ | |
146 | }; | |
147 | ||
148 | #define SDMA_CTRL_REGNUMS sizeof(struct sdma_ctrl)/SDMA_CTRL_REGSIZE | |
149 | ||
150 | /* | |
151 | * DMAC Register Index Enumeration | |
152 | * | |
153 | * [2]: http://www.xilinx.com/support/documentation/user_guides/ug200.pdf | |
154 | * page 244, DMA Controller -- Programming Interface and Registers | |
155 | */ | |
156 | enum dmac_ctrl { | |
157 | /* Transmit Registers */ | |
158 | TX_NXTDESC_PTR = 0, /* TX Next Description Pointer */ | |
159 | TX_CURBUF_ADDR, /* TX Current Buffer Address */ | |
160 | TX_CURBUF_LENGTH, /* TX Current Buffer Length */ | |
161 | TX_CURDESC_PTR, /* TX Current Descriptor Pointer */ | |
162 | TX_TAILDESC_PTR, /* TX Tail Descriptor Pointer */ | |
163 | TX_CHNL_CTRL, /* TX Channel Control */ | |
164 | TX_IRQ_REG, /* TX Interrupt Register */ | |
165 | TX_CHNL_STS, /* TX Status Register */ | |
166 | /* Receive Registers */ | |
167 | RX_NXTDESC_PTR, /* RX Next Descriptor Pointer */ | |
168 | RX_CURBUF_ADDR, /* RX Current Buffer Address */ | |
169 | RX_CURBUF_LENGTH, /* RX Current Buffer Length */ | |
170 | RX_CURDESC_PTR, /* RX Current Descriptor Pointer */ | |
171 | RX_TAILDESC_PTR, /* RX Tail Descriptor Pointer */ | |
172 | RX_CHNL_CTRL, /* RX Channel Control */ | |
173 | RX_IRQ_REG, /* RX Interrupt Register */ | |
174 | RX_CHNL_STS, /* RX Status Register */ | |
175 | /* Control Registers */ | |
176 | DMA_CONTROL_REG /* DMA Control Register */ | |
177 | }; | |
178 | ||
179 | /* Rx/Tx Channel Control Register (*_chnl_ctrl), [1] p163, [2] p246/p252 */ | |
180 | #define CHNL_CTRL_ITO_POS 24 | |
181 | #define CHNL_CTRL_ITO_MASK (0xFF << CHNL_CTRL_ITO_POS) | |
182 | #define CHNL_CTRL_IC_POS 16 | |
183 | #define CHNL_CTRL_IC_MASK (0xFF << CHNL_CTRL_IC_POS) | |
184 | #define CHNL_CTRL_MSBADDR_POS 12 | |
185 | #define CHNL_CTRL_MSBADDR_MASK (0xF << CHNL_CTRL_MSBADDR_POS) | |
186 | #define CHNL_CTRL_AME (1 << 11) | |
187 | #define CHNL_CTRL_OBWC (1 << 10) | |
188 | #define CHNL_CTRL_IOE (1 << 9) | |
189 | #define CHNL_CTRL_LIC (1 << 8) | |
190 | #define CHNL_CTRL_IE (1 << 7) | |
191 | #define CHNL_CTRL_IEE (1 << 2) | |
192 | #define CHNL_CTRL_IDE (1 << 1) | |
193 | #define CHNL_CTRL_ICE (1 << 0) | |
194 | ||
195 | /* All interrupt enable bits */ | |
196 | #define CHNL_CTRL_IRQ_MASK (CHNL_CTRL_IE | \ | |
197 | CHNL_CTRL_IEE | \ | |
198 | CHNL_CTRL_IDE | \ | |
199 | CHNL_CTRL_ICE) | |
200 | ||
201 | /* Rx/Tx Interrupt Status Register (*_irq_reg), [1] p164, [2] p247/p253 */ | |
202 | #define IRQ_REG_DTV_POS 24 | |
203 | #define IRQ_REG_DTV_MASK (0xFF << IRQ_REG_DTV_POS) | |
204 | #define IRQ_REG_CCV_POS 16 | |
205 | #define IRQ_REG_CCV_MASK (0xFF << IRQ_REG_CCV_POS) | |
206 | #define IRQ_REG_WRCQ_EMPTY (1 << 14) | |
207 | #define IRQ_REG_CIC_POS 10 | |
208 | #define IRQ_REG_CIC_MASK (0xF << IRQ_REG_CIC_POS) | |
209 | #define IRQ_REG_DIC_POS 8 | |
210 | #define IRQ_REG_DIC_MASK (3 << 8) | |
211 | #define IRQ_REG_PLB_RD_NMI (1 << 4) | |
212 | #define IRQ_REG_PLB_WR_NMI (1 << 3) | |
213 | #define IRQ_REG_EI (1 << 2) | |
214 | #define IRQ_REG_DI (1 << 1) | |
215 | #define IRQ_REG_CI (1 << 0) | |
216 | ||
217 | /* All interrupt bits */ | |
218 | #define IRQ_REG_IRQ_MASK (IRQ_REG_PLB_RD_NMI | \ | |
219 | IRQ_REG_PLB_WR_NMI | \ | |
220 | IRQ_REG_EI | IRQ_REG_DI | IRQ_REG_CI) | |
221 | ||
222 | /* Rx/Tx Channel Status Register (*_chnl_sts), [1] p165, [2] p249/p255 */ | |
223 | #define CHNL_STS_ERROR_TAIL (1 << 21) | |
224 | #define CHNL_STS_ERROR_CMP (1 << 20) | |
225 | #define CHNL_STS_ERROR_ADDR (1 << 19) | |
226 | #define CHNL_STS_ERROR_NXTP (1 << 18) | |
227 | #define CHNL_STS_ERROR_CURP (1 << 17) | |
228 | #define CHNL_STS_ERROR_BSYWR (1 << 16) | |
229 | #define CHNL_STS_ERROR (1 << 7) | |
230 | #define CHNL_STS_IOE (1 << 6) | |
231 | #define CHNL_STS_SOE (1 << 5) | |
232 | #define CHNL_STS_CMPLT (1 << 4) | |
233 | #define CHNL_STS_SOP (1 << 3) | |
234 | #define CHNL_STS_EOP (1 << 2) | |
235 | #define CHNL_STS_EBUSY (1 << 1) | |
236 | ||
237 | /* DMA Control Register (dma_control_reg), [1] p166, [2] p256 */ | |
238 | #define DMA_CONTROL_PLBED (1 << 5) | |
239 | #define DMA_CONTROL_RXOCEID (1 << 4) | |
240 | #define DMA_CONTROL_TXOCEID (1 << 3) | |
241 | #define DMA_CONTROL_TPE (1 << 2) | |
242 | #define DMA_CONTROL_RESET (1 << 0) | |
243 | ||
df482650 SL |
244 | /* Xilinx Processor Local Bus (PLB) in/out accessors */ |
245 | unsigned ll_temac_xlplb_in32(phys_addr_t base); | |
246 | void ll_temac_xlplb_out32(phys_addr_t base, unsigned value); | |
247 | ||
248 | /* collect all register addresses for Xilinx PLB in/out accessors */ | |
249 | void ll_temac_collect_xlplb_sdma_reg_addr(struct eth_device *dev); | |
250 | ||
251 | /* initialize both Rx/Tx buffer descriptors */ | |
252 | int ll_temac_init_sdma(struct eth_device *dev); | |
253 | ||
254 | /* halt both Rx/Tx transfers */ | |
255 | int ll_temac_halt_sdma(struct eth_device *dev); | |
256 | ||
257 | /* reset SDMA and IRQ, disable interrupts and errors */ | |
258 | int ll_temac_reset_sdma(struct eth_device *dev); | |
259 | ||
260 | /* receive buffered data from SDMA (polling ISR) */ | |
261 | int ll_temac_recv_sdma(struct eth_device *dev); | |
262 | ||
263 | /* send buffered data to SDMA */ | |
f22ff1ab | 264 | int ll_temac_send_sdma(struct eth_device *dev, void *packet, int length); |
df482650 SL |
265 | |
266 | #endif /* _XILINX_LL_TEMAC_SDMA_ */ |