xref: /openbmc/linux/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c (revision e4781421e883340b796da5a724bda7226817990b)
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,
88 			       struct stmmac_dma_cfg *dma_cfg,
89 			       u32 dma_tx, u32 dma_rx, int atds)
90 {
91 	u32 value = readl(ioaddr + DMA_BUS_MODE);
92 	int txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
93 	int rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
94 
95 	/*
96 	 * Set the DMA PBL (Programmable Burst Length) mode.
97 	 *
98 	 * Note: before stmmac core 3.50 this mode bit was 4xPBL, and
99 	 * post 3.5 mode bit acts as 8*PBL.
100 	 */
101 	if (dma_cfg->pblx8)
102 		value |= DMA_BUS_MODE_MAXPBL;
103 	value |= DMA_BUS_MODE_USP;
104 	value &= ~(DMA_BUS_MODE_PBL_MASK | DMA_BUS_MODE_RPBL_MASK);
105 	value |= (txpbl << DMA_BUS_MODE_PBL_SHIFT);
106 	value |= (rxpbl << DMA_BUS_MODE_RPBL_SHIFT);
107 
108 	/* Set the Fixed burst mode */
109 	if (dma_cfg->fixed_burst)
110 		value |= DMA_BUS_MODE_FB;
111 
112 	/* Mixed Burst has no effect when fb is set */
113 	if (dma_cfg->mixed_burst)
114 		value |= DMA_BUS_MODE_MB;
115 
116 	if (atds)
117 		value |= DMA_BUS_MODE_ATDS;
118 
119 	if (dma_cfg->aal)
120 		value |= DMA_BUS_MODE_AAL;
121 
122 	writel(value, ioaddr + DMA_BUS_MODE);
123 
124 	/* Mask interrupts by writing to CSR7 */
125 	writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
126 
127 	/* RX/TX descriptor base address lists must be written into
128 	 * DMA CSR3 and CSR4, respectively
129 	 */
130 	writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
131 	writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
132 }
133 
134 static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz)
135 {
136 	csr6 &= ~DMA_CONTROL_RFA_MASK;
137 	csr6 &= ~DMA_CONTROL_RFD_MASK;
138 
139 	/* Leave flow control disabled if receive fifo size is less than
140 	 * 4K or 0. Otherwise, send XOFF when fifo is 1K less than full,
141 	 * and send XON when 2K less than full.
142 	 */
143 	if (rxfifosz < 4096) {
144 		csr6 &= ~DMA_CONTROL_EFC;
145 		pr_debug("GMAC: disabling flow control, rxfifo too small(%d)\n",
146 			 rxfifosz);
147 	} else {
148 		csr6 |= DMA_CONTROL_EFC;
149 		csr6 |= RFA_FULL_MINUS_1K;
150 		csr6 |= RFD_FULL_MINUS_2K;
151 	}
152 	return csr6;
153 }
154 
155 static void dwmac1000_dma_operation_mode(void __iomem *ioaddr, int txmode,
156 					 int rxmode, int rxfifosz)
157 {
158 	u32 csr6 = readl(ioaddr + DMA_CONTROL);
159 
160 	if (txmode == SF_DMA_MODE) {
161 		pr_debug("GMAC: enable TX store and forward mode\n");
162 		/* Transmit COE type 2 cannot be done in cut-through mode. */
163 		csr6 |= DMA_CONTROL_TSF;
164 		/* Operating on second frame increase the performance
165 		 * especially when transmit store-and-forward is used.
166 		 */
167 		csr6 |= DMA_CONTROL_OSF;
168 	} else {
169 		pr_debug("GMAC: disabling TX SF (threshold %d)\n", txmode);
170 		csr6 &= ~DMA_CONTROL_TSF;
171 		csr6 &= DMA_CONTROL_TC_TX_MASK;
172 		/* Set the transmit threshold */
173 		if (txmode <= 32)
174 			csr6 |= DMA_CONTROL_TTC_32;
175 		else if (txmode <= 64)
176 			csr6 |= DMA_CONTROL_TTC_64;
177 		else if (txmode <= 128)
178 			csr6 |= DMA_CONTROL_TTC_128;
179 		else if (txmode <= 192)
180 			csr6 |= DMA_CONTROL_TTC_192;
181 		else
182 			csr6 |= DMA_CONTROL_TTC_256;
183 	}
184 
185 	if (rxmode == SF_DMA_MODE) {
186 		pr_debug("GMAC: enable RX store and forward mode\n");
187 		csr6 |= DMA_CONTROL_RSF;
188 	} else {
189 		pr_debug("GMAC: disable RX SF mode (threshold %d)\n", rxmode);
190 		csr6 &= ~DMA_CONTROL_RSF;
191 		csr6 &= DMA_CONTROL_TC_RX_MASK;
192 		if (rxmode <= 32)
193 			csr6 |= DMA_CONTROL_RTC_32;
194 		else if (rxmode <= 64)
195 			csr6 |= DMA_CONTROL_RTC_64;
196 		else if (rxmode <= 96)
197 			csr6 |= DMA_CONTROL_RTC_96;
198 		else
199 			csr6 |= DMA_CONTROL_RTC_128;
200 	}
201 
202 	/* Configure flow control based on rx fifo size */
203 	csr6 = dwmac1000_configure_fc(csr6, rxfifosz);
204 
205 	writel(csr6, ioaddr + DMA_CONTROL);
206 }
207 
208 static void dwmac1000_dump_dma_regs(void __iomem *ioaddr)
209 {
210 	int i;
211 	pr_info(" DMA registers\n");
212 	for (i = 0; i < 22; i++) {
213 		if ((i < 9) || (i > 17)) {
214 			int offset = i * 4;
215 			pr_err("\t Reg No. %d (offset 0x%x): 0x%08x\n", i,
216 			       (DMA_BUS_MODE + offset),
217 			       readl(ioaddr + DMA_BUS_MODE + offset));
218 		}
219 	}
220 }
221 
222 static void dwmac1000_get_hw_feature(void __iomem *ioaddr,
223 				     struct dma_features *dma_cap)
224 {
225 	u32 hw_cap = readl(ioaddr + DMA_HW_FEATURE);
226 
227 	dma_cap->mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL);
228 	dma_cap->mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1;
229 	dma_cap->half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2;
230 	dma_cap->hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4;
231 	dma_cap->multi_addr = (hw_cap & DMA_HW_FEAT_ADDMAC) >> 5;
232 	dma_cap->pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6;
233 	dma_cap->sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8;
234 	dma_cap->pmt_remote_wake_up = (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9;
235 	dma_cap->pmt_magic_frame = (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10;
236 	/* MMC */
237 	dma_cap->rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11;
238 	/* IEEE 1588-2002 */
239 	dma_cap->time_stamp =
240 	    (hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12;
241 	/* IEEE 1588-2008 */
242 	dma_cap->atime_stamp = (hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13;
243 	/* 802.3az - Energy-Efficient Ethernet (EEE) */
244 	dma_cap->eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14;
245 	dma_cap->av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15;
246 	/* TX and RX csum */
247 	dma_cap->tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16;
248 	dma_cap->rx_coe_type1 = (hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17;
249 	dma_cap->rx_coe_type2 = (hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18;
250 	dma_cap->rxfifo_over_2048 = (hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19;
251 	/* TX and RX number of channels */
252 	dma_cap->number_rx_channel = (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20;
253 	dma_cap->number_tx_channel = (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22;
254 	/* Alternate (enhanced) DESC mode */
255 	dma_cap->enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
256 }
257 
258 static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt)
259 {
260 	writel(riwt, ioaddr + DMA_RX_WATCHDOG);
261 }
262 
263 const struct stmmac_dma_ops dwmac1000_dma_ops = {
264 	.reset = dwmac_dma_reset,
265 	.init = dwmac1000_dma_init,
266 	.axi = dwmac1000_dma_axi,
267 	.dump_regs = dwmac1000_dump_dma_regs,
268 	.dma_mode = dwmac1000_dma_operation_mode,
269 	.enable_dma_transmission = dwmac_enable_dma_transmission,
270 	.enable_dma_irq = dwmac_enable_dma_irq,
271 	.disable_dma_irq = dwmac_disable_dma_irq,
272 	.start_tx = dwmac_dma_start_tx,
273 	.stop_tx = dwmac_dma_stop_tx,
274 	.start_rx = dwmac_dma_start_rx,
275 	.stop_rx = dwmac_dma_stop_rx,
276 	.dma_interrupt = dwmac_dma_interrupt,
277 	.get_hw_feature = dwmac1000_get_hw_feature,
278 	.rx_watchdog = dwmac1000_rx_watchdog,
279 };
280