Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / 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 int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb,
34                               int burst_len, u32 dma_tx, u32 dma_rx, int atds)
35 {
36         u32 value = readl(ioaddr + DMA_BUS_MODE);
37         int limit;
38
39         /* DMA SW reset */
40         value |= DMA_BUS_MODE_SFT_RESET;
41         writel(value, ioaddr + DMA_BUS_MODE);
42         limit = 10;
43         while (limit--) {
44                 if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
45                         break;
46                 mdelay(10);
47         }
48         if (limit < 0)
49                 return -EBUSY;
50
51         /*
52          * Set the DMA PBL (Programmable Burst Length) mode
53          * Before stmmac core 3.50 this mode bit was 4xPBL, and
54          * post 3.5 mode bit acts as 8*PBL.
55          * For core rev < 3.5, when the core is set for 4xPBL mode, the
56          * DMA transfers the data in 4, 8, 16, 32, 64 & 128 beats
57          * depending on pbl value.
58          * For core rev > 3.5, when the core is set for 8xPBL mode, the
59          * DMA transfers the data in 8, 16, 32, 64, 128 & 256 beats
60          * depending on pbl value.
61          */
62         value = DMA_BUS_MODE_PBL | ((pbl << DMA_BUS_MODE_PBL_SHIFT) |
63                                     (pbl << DMA_BUS_MODE_RPBL_SHIFT));
64
65         /* Set the Fixed burst mode */
66         if (fb)
67                 value |= DMA_BUS_MODE_FB;
68
69         /* Mixed Burst has no effect when fb is set */
70         if (mb)
71                 value |= DMA_BUS_MODE_MB;
72
73         if (atds)
74                 value |= DMA_BUS_MODE_ATDS;
75
76         writel(value, ioaddr + DMA_BUS_MODE);
77
78         /* In case of GMAC AXI configuration, program the DMA_AXI_BUS_MODE
79          * for supported bursts.
80          *
81          * Note: This is applicable only for revision GMACv3.61a. For
82          * older version this register is reserved and shall have no
83          * effect.
84          *
85          * Note:
86          *  For Fixed Burst Mode: if we directly write 0xFF to this
87          *  register using the configurations pass from platform code,
88          *  this would ensure that all bursts supported by core are set
89          *  and those which are not supported would remain ineffective.
90          *
91          *  For Non Fixed Burst Mode: provide the maximum value of the
92          *  burst length. Any burst equal or below the provided burst
93          *  length would be allowed to perform.
94          */
95         writel(burst_len, ioaddr + DMA_AXI_BUS_MODE);
96
97         /* Mask interrupts by writing to CSR7 */
98         writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
99
100         /* RX/TX descriptor base address lists must be written into
101          * DMA CSR3 and CSR4, respectively
102          */
103         writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
104         writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
105
106         return 0;
107 }
108
109 static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz)
110 {
111         csr6 &= ~DMA_CONTROL_RFA_MASK;
112         csr6 &= ~DMA_CONTROL_RFD_MASK;
113
114         /* Leave flow control disabled if receive fifo size is less than
115          * 4K or 0. Otherwise, send XOFF when fifo is 1K less than full,
116          * and send XON when 2K less than full.
117          */
118         if (rxfifosz < 4096) {
119                 csr6 &= ~DMA_CONTROL_EFC;
120                 pr_debug("GMAC: disabling flow control, rxfifo too small(%d)\n",
121                          rxfifosz);
122         } else {
123                 csr6 |= DMA_CONTROL_EFC;
124                 csr6 |= RFA_FULL_MINUS_1K;
125                 csr6 |= RFD_FULL_MINUS_2K;
126         }
127         return csr6;
128 }
129
130 static void dwmac1000_dma_operation_mode(void __iomem *ioaddr, int txmode,
131                                          int rxmode, int rxfifosz)
132 {
133         u32 csr6 = readl(ioaddr + DMA_CONTROL);
134
135         if (txmode == SF_DMA_MODE) {
136                 pr_debug("GMAC: enable TX store and forward mode\n");
137                 /* Transmit COE type 2 cannot be done in cut-through mode. */
138                 csr6 |= DMA_CONTROL_TSF;
139                 /* Operating on second frame increase the performance
140                  * especially when transmit store-and-forward is used.
141                  */
142                 csr6 |= DMA_CONTROL_OSF;
143         } else {
144                 pr_debug("GMAC: disabling TX SF (threshold %d)\n", txmode);
145                 csr6 &= ~DMA_CONTROL_TSF;
146                 csr6 &= DMA_CONTROL_TC_TX_MASK;
147                 /* Set the transmit threshold */
148                 if (txmode <= 32)
149                         csr6 |= DMA_CONTROL_TTC_32;
150                 else if (txmode <= 64)
151                         csr6 |= DMA_CONTROL_TTC_64;
152                 else if (txmode <= 128)
153                         csr6 |= DMA_CONTROL_TTC_128;
154                 else if (txmode <= 192)
155                         csr6 |= DMA_CONTROL_TTC_192;
156                 else
157                         csr6 |= DMA_CONTROL_TTC_256;
158         }
159
160         if (rxmode == SF_DMA_MODE) {
161                 pr_debug("GMAC: enable RX store and forward mode\n");
162                 csr6 |= DMA_CONTROL_RSF;
163         } else {
164                 pr_debug("GMAC: disable RX SF mode (threshold %d)\n", rxmode);
165                 csr6 &= ~DMA_CONTROL_RSF;
166                 csr6 &= DMA_CONTROL_TC_RX_MASK;
167                 if (rxmode <= 32)
168                         csr6 |= DMA_CONTROL_RTC_32;
169                 else if (rxmode <= 64)
170                         csr6 |= DMA_CONTROL_RTC_64;
171                 else if (rxmode <= 96)
172                         csr6 |= DMA_CONTROL_RTC_96;
173                 else
174                         csr6 |= DMA_CONTROL_RTC_128;
175         }
176
177         /* Configure flow control based on rx fifo size */
178         csr6 = dwmac1000_configure_fc(csr6, rxfifosz);
179
180         writel(csr6, ioaddr + DMA_CONTROL);
181 }
182
183 static void dwmac1000_dump_dma_regs(void __iomem *ioaddr)
184 {
185         int i;
186         pr_info(" DMA registers\n");
187         for (i = 0; i < 22; i++) {
188                 if ((i < 9) || (i > 17)) {
189                         int offset = i * 4;
190                         pr_err("\t Reg No. %d (offset 0x%x): 0x%08x\n", i,
191                                (DMA_BUS_MODE + offset),
192                                readl(ioaddr + DMA_BUS_MODE + offset));
193                 }
194         }
195 }
196
197 static unsigned int dwmac1000_get_hw_feature(void __iomem *ioaddr)
198 {
199         return readl(ioaddr + DMA_HW_FEATURE);
200 }
201
202 static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt)
203 {
204         writel(riwt, ioaddr + DMA_RX_WATCHDOG);
205 }
206
207 const struct stmmac_dma_ops dwmac1000_dma_ops = {
208         .init = dwmac1000_dma_init,
209         .dump_regs = dwmac1000_dump_dma_regs,
210         .dma_mode = dwmac1000_dma_operation_mode,
211         .enable_dma_transmission = dwmac_enable_dma_transmission,
212         .enable_dma_irq = dwmac_enable_dma_irq,
213         .disable_dma_irq = dwmac_disable_dma_irq,
214         .start_tx = dwmac_dma_start_tx,
215         .stop_tx = dwmac_dma_stop_tx,
216         .start_rx = dwmac_dma_start_rx,
217         .stop_rx = dwmac_dma_stop_rx,
218         .dma_interrupt = dwmac_dma_interrupt,
219         .get_hw_feature = dwmac1000_get_hw_feature,
220         .rx_watchdog = dwmac1000_rx_watchdog,
221 };