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