xref: /linux/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c (revision e58e871becec2d3b04ed91c0c16fe8deac9c9dfa)
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 < 22; i++)
209 		if ((i < 9) || (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 };
273