GNU Linux-libre 4.9-gnu1
[releases.git] / drivers / net / ethernet / stmicro / stmmac / dwmac1000_dma.c
1 /*******************************************************************************
2   This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
3   DWC Ether MAC 10/100/1000 Universal version 3.41a  has been used for
4   developing this code.
5
6   This contains the functions to handle the dma.
7
8   Copyright (C) 2007-2009  STMicroelectronics Ltd
9
10   This program is free software; you can redistribute it and/or modify it
11   under the terms and conditions of the GNU General Public License,
12   version 2, as published by the Free Software Foundation.
13
14   This program is distributed in the hope it will be useful, but WITHOUT
15   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17   more details.
18
19   You should have received a copy of the GNU General Public License along with
20   this program; if not, write to the Free Software Foundation, Inc.,
21   51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
22
23   The full GNU General Public License is included in this distribution in
24   the file called "COPYING".
25
26   Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
27 *******************************************************************************/
28
29 #include <asm/io.h>
30 #include "dwmac1000.h"
31 #include "dwmac_dma.h"
32
33 static void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
34 {
35         u32 value = readl(ioaddr + DMA_AXI_BUS_MODE);
36         int i;
37
38         pr_info("dwmac1000: Master AXI performs %s burst length\n",
39                 !(value & DMA_AXI_UNDEF) ? "fixed" : "any");
40
41         if (axi->axi_lpi_en)
42                 value |= DMA_AXI_EN_LPI;
43         if (axi->axi_xit_frm)
44                 value |= DMA_AXI_LPI_XIT_FRM;
45
46         value &= ~DMA_AXI_WR_OSR_LMT;
47         value |= (axi->axi_wr_osr_lmt & DMA_AXI_WR_OSR_LMT_MASK) <<
48                  DMA_AXI_WR_OSR_LMT_SHIFT;
49
50         value &= ~DMA_AXI_RD_OSR_LMT;
51         value |= (axi->axi_rd_osr_lmt & DMA_AXI_RD_OSR_LMT_MASK) <<
52                  DMA_AXI_RD_OSR_LMT_SHIFT;
53
54         /* Depending on the UNDEF bit the Master AXI will perform any burst
55          * length according to the BLEN programmed (by default all BLEN are
56          * set).
57          */
58         for (i = 0; i < AXI_BLEN; i++) {
59                 switch (axi->axi_blen[i]) {
60                 case 256:
61                         value |= DMA_AXI_BLEN256;
62                         break;
63                 case 128:
64                         value |= DMA_AXI_BLEN128;
65                         break;
66                 case 64:
67                         value |= DMA_AXI_BLEN64;
68                         break;
69                 case 32:
70                         value |= DMA_AXI_BLEN32;
71                         break;
72                 case 16:
73                         value |= DMA_AXI_BLEN16;
74                         break;
75                 case 8:
76                         value |= DMA_AXI_BLEN8;
77                         break;
78                 case 4:
79                         value |= DMA_AXI_BLEN4;
80                         break;
81                 }
82         }
83
84         writel(value, ioaddr + DMA_AXI_BUS_MODE);
85 }
86
87 static void dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb,
88                                int aal, u32 dma_tx, u32 dma_rx, int atds)
89 {
90         u32 value = readl(ioaddr + DMA_BUS_MODE);
91
92         /*
93          * Set the DMA PBL (Programmable Burst Length) mode.
94          *
95          * Note: before stmmac core 3.50 this mode bit was 4xPBL, and
96          * post 3.5 mode bit acts as 8*PBL.
97          *
98          * This configuration doesn't take care about the Separate PBL
99          * so only the bits: 13-8 are programmed with the PBL passed from the
100          * platform.
101          */
102         value |= DMA_BUS_MODE_MAXPBL;
103         value &= ~DMA_BUS_MODE_PBL_MASK;
104         value |= (pbl << DMA_BUS_MODE_PBL_SHIFT);
105
106         /* Set the Fixed burst mode */
107         if (fb)
108                 value |= DMA_BUS_MODE_FB;
109
110         /* Mixed Burst has no effect when fb is set */
111         if (mb)
112                 value |= DMA_BUS_MODE_MB;
113
114         if (atds)
115                 value |= DMA_BUS_MODE_ATDS;
116
117         if (aal)
118                 value |= DMA_BUS_MODE_AAL;
119
120         writel(value, ioaddr + DMA_BUS_MODE);
121
122         /* Mask interrupts by writing to CSR7 */
123         writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
124
125         /* RX/TX descriptor base address lists must be written into
126          * DMA CSR3 and CSR4, respectively
127          */
128         writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
129         writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
130 }
131
132 static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz)
133 {
134         csr6 &= ~DMA_CONTROL_RFA_MASK;
135         csr6 &= ~DMA_CONTROL_RFD_MASK;
136
137         /* Leave flow control disabled if receive fifo size is less than
138          * 4K or 0. Otherwise, send XOFF when fifo is 1K less than full,
139          * and send XON when 2K less than full.
140          */
141         if (rxfifosz < 4096) {
142                 csr6 &= ~DMA_CONTROL_EFC;
143                 pr_debug("GMAC: disabling flow control, rxfifo too small(%d)\n",
144                          rxfifosz);
145         } else {
146                 csr6 |= DMA_CONTROL_EFC;
147                 csr6 |= RFA_FULL_MINUS_1K;
148                 csr6 |= RFD_FULL_MINUS_2K;
149         }
150         return csr6;
151 }
152
153 static void dwmac1000_dma_operation_mode(void __iomem *ioaddr, int txmode,
154                                          int rxmode, int rxfifosz)
155 {
156         u32 csr6 = readl(ioaddr + DMA_CONTROL);
157
158         if (txmode == SF_DMA_MODE) {
159                 pr_debug("GMAC: enable TX store and forward mode\n");
160                 /* Transmit COE type 2 cannot be done in cut-through mode. */
161                 csr6 |= DMA_CONTROL_TSF;
162                 /* Operating on second frame increase the performance
163                  * especially when transmit store-and-forward is used.
164                  */
165                 csr6 |= DMA_CONTROL_OSF;
166         } else {
167                 pr_debug("GMAC: disabling TX SF (threshold %d)\n", txmode);
168                 csr6 &= ~DMA_CONTROL_TSF;
169                 csr6 &= DMA_CONTROL_TC_TX_MASK;
170                 /* Set the transmit threshold */
171                 if (txmode <= 32)
172                         csr6 |= DMA_CONTROL_TTC_32;
173                 else if (txmode <= 64)
174                         csr6 |= DMA_CONTROL_TTC_64;
175                 else if (txmode <= 128)
176                         csr6 |= DMA_CONTROL_TTC_128;
177                 else if (txmode <= 192)
178                         csr6 |= DMA_CONTROL_TTC_192;
179                 else
180                         csr6 |= DMA_CONTROL_TTC_256;
181         }
182
183         if (rxmode == SF_DMA_MODE) {
184                 pr_debug("GMAC: enable RX store and forward mode\n");
185                 csr6 |= DMA_CONTROL_RSF;
186         } else {
187                 pr_debug("GMAC: disable RX SF mode (threshold %d)\n", rxmode);
188                 csr6 &= ~DMA_CONTROL_RSF;
189                 csr6 &= DMA_CONTROL_TC_RX_MASK;
190                 if (rxmode <= 32)
191                         csr6 |= DMA_CONTROL_RTC_32;
192                 else if (rxmode <= 64)
193                         csr6 |= DMA_CONTROL_RTC_64;
194                 else if (rxmode <= 96)
195                         csr6 |= DMA_CONTROL_RTC_96;
196                 else
197                         csr6 |= DMA_CONTROL_RTC_128;
198         }
199
200         /* Configure flow control based on rx fifo size */
201         csr6 = dwmac1000_configure_fc(csr6, rxfifosz);
202
203         writel(csr6, ioaddr + DMA_CONTROL);
204 }
205
206 static void dwmac1000_dump_dma_regs(void __iomem *ioaddr)
207 {
208         int i;
209         pr_info(" DMA registers\n");
210         for (i = 0; i < 22; i++) {
211                 if ((i < 9) || (i > 17)) {
212                         int offset = i * 4;
213                         pr_err("\t Reg No. %d (offset 0x%x): 0x%08x\n", i,
214                                (DMA_BUS_MODE + offset),
215                                readl(ioaddr + DMA_BUS_MODE + offset));
216                 }
217         }
218 }
219
220 static void dwmac1000_get_hw_feature(void __iomem *ioaddr,
221                                      struct dma_features *dma_cap)
222 {
223         u32 hw_cap = readl(ioaddr + DMA_HW_FEATURE);
224
225         dma_cap->mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL);
226         dma_cap->mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1;
227         dma_cap->half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2;
228         dma_cap->hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4;
229         dma_cap->multi_addr = (hw_cap & DMA_HW_FEAT_ADDMAC) >> 5;
230         dma_cap->pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6;
231         dma_cap->sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8;
232         dma_cap->pmt_remote_wake_up = (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9;
233         dma_cap->pmt_magic_frame = (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10;
234         /* MMC */
235         dma_cap->rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11;
236         /* IEEE 1588-2002 */
237         dma_cap->time_stamp =
238             (hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12;
239         /* IEEE 1588-2008 */
240         dma_cap->atime_stamp = (hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13;
241         /* 802.3az - Energy-Efficient Ethernet (EEE) */
242         dma_cap->eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14;
243         dma_cap->av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15;
244         /* TX and RX csum */
245         dma_cap->tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16;
246         dma_cap->rx_coe_type1 = (hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17;
247         dma_cap->rx_coe_type2 = (hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18;
248         dma_cap->rxfifo_over_2048 = (hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19;
249         /* TX and RX number of channels */
250         dma_cap->number_rx_channel = (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20;
251         dma_cap->number_tx_channel = (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22;
252         /* Alternate (enhanced) DESC mode */
253         dma_cap->enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
254 }
255
256 static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt)
257 {
258         writel(riwt, ioaddr + DMA_RX_WATCHDOG);
259 }
260
261 const struct stmmac_dma_ops dwmac1000_dma_ops = {
262         .reset = dwmac_dma_reset,
263         .init = dwmac1000_dma_init,
264         .axi = dwmac1000_dma_axi,
265         .dump_regs = dwmac1000_dump_dma_regs,
266         .dma_mode = dwmac1000_dma_operation_mode,
267         .enable_dma_transmission = dwmac_enable_dma_transmission,
268         .enable_dma_irq = dwmac_enable_dma_irq,
269         .disable_dma_irq = dwmac_disable_dma_irq,
270         .start_tx = dwmac_dma_start_tx,
271         .stop_tx = dwmac_dma_stop_tx,
272         .start_rx = dwmac_dma_start_rx,
273         .stop_rx = dwmac_dma_stop_rx,
274         .dma_interrupt = dwmac_dma_interrupt,
275         .get_hw_feature = dwmac1000_get_hw_feature,
276         .rx_watchdog = dwmac1000_rx_watchdog,
277 };