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