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, int atds)
85{
86 u32 value = readl(ioaddr + DMA_BUS_MODE);
87 int txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
88 int rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
89
90
91
92
93
94
95
96 if (dma_cfg->pblx8)
97 value |= DMA_BUS_MODE_MAXPBL;
98 value |= DMA_BUS_MODE_USP;
99 value &= ~(DMA_BUS_MODE_PBL_MASK | DMA_BUS_MODE_RPBL_MASK);
100 value |= (txpbl << DMA_BUS_MODE_PBL_SHIFT);
101 value |= (rxpbl << DMA_BUS_MODE_RPBL_SHIFT);
102
103
104 if (dma_cfg->fixed_burst)
105 value |= DMA_BUS_MODE_FB;
106
107
108 if (dma_cfg->mixed_burst)
109 value |= DMA_BUS_MODE_MB;
110
111 if (atds)
112 value |= DMA_BUS_MODE_ATDS;
113
114 if (dma_cfg->aal)
115 value |= DMA_BUS_MODE_AAL;
116
117 writel(value, ioaddr + DMA_BUS_MODE);
118
119
120 writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
121}
122
123static void dwmac1000_dma_init_rx(void __iomem *ioaddr,
124 struct stmmac_dma_cfg *dma_cfg,
125 dma_addr_t dma_rx_phy, u32 chan)
126{
127
128 writel(lower_32_bits(dma_rx_phy), ioaddr + DMA_RCV_BASE_ADDR);
129}
130
131static void dwmac1000_dma_init_tx(void __iomem *ioaddr,
132 struct stmmac_dma_cfg *dma_cfg,
133 dma_addr_t dma_tx_phy, u32 chan)
134{
135
136 writel(lower_32_bits(dma_tx_phy), ioaddr + DMA_TX_BASE_ADDR);
137}
138
139static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz)
140{
141 csr6 &= ~DMA_CONTROL_RFA_MASK;
142 csr6 &= ~DMA_CONTROL_RFD_MASK;
143
144
145
146
147
148 if (rxfifosz < 4096) {
149 csr6 &= ~DMA_CONTROL_EFC;
150 pr_debug("GMAC: disabling flow control, rxfifo too small(%d)\n",
151 rxfifosz);
152 } else {
153 csr6 |= DMA_CONTROL_EFC;
154 csr6 |= RFA_FULL_MINUS_1K;
155 csr6 |= RFD_FULL_MINUS_2K;
156 }
157 return csr6;
158}
159
160static void dwmac1000_dma_operation_mode_rx(void __iomem *ioaddr, int mode,
161 u32 channel, int fifosz, u8 qmode)
162{
163 u32 csr6 = readl(ioaddr + DMA_CONTROL);
164
165 if (mode == SF_DMA_MODE) {
166 pr_debug("GMAC: enable RX store and forward mode\n");
167 csr6 |= DMA_CONTROL_RSF;
168 } else {
169 pr_debug("GMAC: disable RX SF mode (threshold %d)\n", mode);
170 csr6 &= ~DMA_CONTROL_RSF;
171 csr6 &= DMA_CONTROL_TC_RX_MASK;
172 if (mode <= 32)
173 csr6 |= DMA_CONTROL_RTC_32;
174 else if (mode <= 64)
175 csr6 |= DMA_CONTROL_RTC_64;
176 else if (mode <= 96)
177 csr6 |= DMA_CONTROL_RTC_96;
178 else
179 csr6 |= DMA_CONTROL_RTC_128;
180 }
181
182
183 csr6 = dwmac1000_configure_fc(csr6, fifosz);
184
185 writel(csr6, ioaddr + DMA_CONTROL);
186}
187
188static void dwmac1000_dma_operation_mode_tx(void __iomem *ioaddr, int mode,
189 u32 channel, int fifosz, u8 qmode)
190{
191 u32 csr6 = readl(ioaddr + DMA_CONTROL);
192
193 if (mode == SF_DMA_MODE) {
194 pr_debug("GMAC: enable TX store and forward mode\n");
195
196 csr6 |= DMA_CONTROL_TSF;
197
198
199
200 csr6 |= DMA_CONTROL_OSF;
201 } else {
202 pr_debug("GMAC: disabling TX SF (threshold %d)\n", mode);
203 csr6 &= ~DMA_CONTROL_TSF;
204 csr6 &= DMA_CONTROL_TC_TX_MASK;
205
206 if (mode <= 32)
207 csr6 |= DMA_CONTROL_TTC_32;
208 else if (mode <= 64)
209 csr6 |= DMA_CONTROL_TTC_64;
210 else if (mode <= 128)
211 csr6 |= DMA_CONTROL_TTC_128;
212 else if (mode <= 192)
213 csr6 |= DMA_CONTROL_TTC_192;
214 else
215 csr6 |= DMA_CONTROL_TTC_256;
216 }
217
218 writel(csr6, ioaddr + DMA_CONTROL);
219}
220
221static void dwmac1000_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space)
222{
223 int i;
224
225 for (i = 0; i < NUM_DWMAC1000_DMA_REGS; i++)
226 if ((i < 12) || (i > 17))
227 reg_space[DMA_BUS_MODE / 4 + i] =
228 readl(ioaddr + DMA_BUS_MODE + i * 4);
229}
230
231static void dwmac1000_get_hw_feature(void __iomem *ioaddr,
232 struct dma_features *dma_cap)
233{
234 u32 hw_cap = readl(ioaddr + DMA_HW_FEATURE);
235
236 dma_cap->mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL);
237 dma_cap->mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1;
238 dma_cap->half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2;
239 dma_cap->hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4;
240 dma_cap->multi_addr = (hw_cap & DMA_HW_FEAT_ADDMAC) >> 5;
241 dma_cap->pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6;
242 dma_cap->sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8;
243 dma_cap->pmt_remote_wake_up = (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9;
244 dma_cap->pmt_magic_frame = (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10;
245
246 dma_cap->rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11;
247
248 dma_cap->time_stamp =
249 (hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12;
250
251 dma_cap->atime_stamp = (hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13;
252
253 dma_cap->eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14;
254 dma_cap->av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15;
255
256 dma_cap->tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16;
257 dma_cap->rx_coe_type1 = (hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17;
258 dma_cap->rx_coe_type2 = (hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18;
259 dma_cap->rxfifo_over_2048 = (hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19;
260
261 dma_cap->number_rx_channel = (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20;
262 dma_cap->number_tx_channel = (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22;
263
264 dma_cap->enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
265}
266
267static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt,
268 u32 queue)
269{
270 writel(riwt, ioaddr + DMA_RX_WATCHDOG);
271}
272
273const struct stmmac_dma_ops dwmac1000_dma_ops = {
274 .reset = dwmac_dma_reset,
275 .init = dwmac1000_dma_init,
276 .init_rx_chan = dwmac1000_dma_init_rx,
277 .init_tx_chan = dwmac1000_dma_init_tx,
278 .axi = dwmac1000_dma_axi,
279 .dump_regs = dwmac1000_dump_dma_regs,
280 .dma_rx_mode = dwmac1000_dma_operation_mode_rx,
281 .dma_tx_mode = dwmac1000_dma_operation_mode_tx,
282 .enable_dma_transmission = dwmac_enable_dma_transmission,
283 .enable_dma_irq = dwmac_enable_dma_irq,
284 .disable_dma_irq = dwmac_disable_dma_irq,
285 .start_tx = dwmac_dma_start_tx,
286 .stop_tx = dwmac_dma_stop_tx,
287 .start_rx = dwmac_dma_start_rx,
288 .stop_rx = dwmac_dma_stop_rx,
289 .dma_interrupt = dwmac_dma_interrupt,
290 .get_hw_feature = dwmac1000_get_hw_feature,
291 .rx_watchdog = dwmac1000_rx_watchdog,
292};
293