1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include <asm/io.h>
26#include "dwmac1000.h"
27#include "dwmac_dma.h"
28
29static 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
51
52
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
83static 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
93
94
95
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
105 if (dma_cfg->fixed_burst)
106 value |= DMA_BUS_MODE_FB;
107
108
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
121 writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
122
123
124
125
126 writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
127 writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
128}
129
130static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz)
131{
132 csr6 &= ~DMA_CONTROL_RFA_MASK;
133 csr6 &= ~DMA_CONTROL_RFD_MASK;
134
135
136
137
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
151static 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
159 csr6 |= DMA_CONTROL_TSF;
160
161
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
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
199 csr6 = dwmac1000_configure_fc(csr6, rxfifosz);
200
201 writel(csr6, ioaddr + DMA_CONTROL);
202}
203
204static 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
214static 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
229 dma_cap->rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11;
230
231 dma_cap->time_stamp =
232 (hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12;
233
234 dma_cap->atime_stamp = (hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13;
235
236 dma_cap->eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14;
237 dma_cap->av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15;
238
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
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
247 dma_cap->enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
248}
249
250static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt,
251 u32 number_chan)
252{
253 writel(riwt, ioaddr + DMA_RX_WATCHDOG);
254}
255
256const 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