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