1 // SPDX-License-Identifier: GPL-2.0-only
2 /*******************************************************************************
3 This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
4 DWC Ether MAC 10/100/1000 Universal version 3.41a has been used for
7 This contains the functions to handle the dma.
9 Copyright (C) 2007-2009 STMicroelectronics Ltd
12 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
13 *******************************************************************************/
16 #include "dwmac1000.h"
17 #include "dwmac_dma.h"
19 static void dwmac1000_dma_axi(void __iomem
*ioaddr
, struct stmmac_axi
*axi
)
21 u32 value
= readl(ioaddr
+ DMA_AXI_BUS_MODE
);
24 pr_info("dwmac1000: Master AXI performs %s burst length\n",
25 !(value
& DMA_AXI_UNDEF
) ? "fixed" : "any");
28 value
|= DMA_AXI_EN_LPI
;
30 value
|= DMA_AXI_LPI_XIT_FRM
;
32 value
&= ~DMA_AXI_WR_OSR_LMT
;
33 value
|= (axi
->axi_wr_osr_lmt
& DMA_AXI_WR_OSR_LMT_MASK
) <<
34 DMA_AXI_WR_OSR_LMT_SHIFT
;
36 value
&= ~DMA_AXI_RD_OSR_LMT
;
37 value
|= (axi
->axi_rd_osr_lmt
& DMA_AXI_RD_OSR_LMT_MASK
) <<
38 DMA_AXI_RD_OSR_LMT_SHIFT
;
40 /* Depending on the UNDEF bit the Master AXI will perform any burst
41 * length according to the BLEN programmed (by default all BLEN are
44 for (i
= 0; i
< AXI_BLEN
; i
++) {
45 switch (axi
->axi_blen
[i
]) {
47 value
|= DMA_AXI_BLEN256
;
50 value
|= DMA_AXI_BLEN128
;
53 value
|= DMA_AXI_BLEN64
;
56 value
|= DMA_AXI_BLEN32
;
59 value
|= DMA_AXI_BLEN16
;
62 value
|= DMA_AXI_BLEN8
;
65 value
|= DMA_AXI_BLEN4
;
70 writel(value
, ioaddr
+ DMA_AXI_BUS_MODE
);
73 static void dwmac1000_dma_init(void __iomem
*ioaddr
,
74 struct stmmac_dma_cfg
*dma_cfg
, int atds
)
76 u32 value
= readl(ioaddr
+ DMA_BUS_MODE
);
77 int txpbl
= dma_cfg
->txpbl
?: dma_cfg
->pbl
;
78 int rxpbl
= dma_cfg
->rxpbl
?: dma_cfg
->pbl
;
81 * Set the DMA PBL (Programmable Burst Length) mode.
83 * Note: before stmmac core 3.50 this mode bit was 4xPBL, and
84 * post 3.5 mode bit acts as 8*PBL.
87 value
|= DMA_BUS_MODE_MAXPBL
;
88 value
|= DMA_BUS_MODE_USP
;
89 value
&= ~(DMA_BUS_MODE_PBL_MASK
| DMA_BUS_MODE_RPBL_MASK
);
90 value
|= (txpbl
<< DMA_BUS_MODE_PBL_SHIFT
);
91 value
|= (rxpbl
<< DMA_BUS_MODE_RPBL_SHIFT
);
93 /* Set the Fixed burst mode */
94 if (dma_cfg
->fixed_burst
)
95 value
|= DMA_BUS_MODE_FB
;
97 /* Mixed Burst has no effect when fb is set */
98 if (dma_cfg
->mixed_burst
)
99 value
|= DMA_BUS_MODE_MB
;
102 value
|= DMA_BUS_MODE_ATDS
;
105 value
|= DMA_BUS_MODE_AAL
;
107 writel(value
, ioaddr
+ DMA_BUS_MODE
);
109 /* Mask interrupts by writing to CSR7 */
110 writel(DMA_INTR_DEFAULT_MASK
, ioaddr
+ DMA_INTR_ENA
);
113 static void dwmac1000_dma_init_rx(void __iomem
*ioaddr
,
114 struct stmmac_dma_cfg
*dma_cfg
,
115 dma_addr_t dma_rx_phy
, u32 chan
)
117 /* RX descriptor base address list must be written into DMA CSR3 */
118 writel(lower_32_bits(dma_rx_phy
), ioaddr
+ DMA_RCV_BASE_ADDR
);
121 static void dwmac1000_dma_init_tx(void __iomem
*ioaddr
,
122 struct stmmac_dma_cfg
*dma_cfg
,
123 dma_addr_t dma_tx_phy
, u32 chan
)
125 /* TX descriptor base address list must be written into DMA CSR4 */
126 writel(lower_32_bits(dma_tx_phy
), ioaddr
+ DMA_TX_BASE_ADDR
);
129 static u32
dwmac1000_configure_fc(u32 csr6
, int rxfifosz
)
131 csr6
&= ~DMA_CONTROL_RFA_MASK
;
132 csr6
&= ~DMA_CONTROL_RFD_MASK
;
134 /* Leave flow control disabled if receive fifo size is less than
135 * 4K or 0. Otherwise, send XOFF when fifo is 1K less than full,
136 * and send XON when 2K less than full.
138 if (rxfifosz
< 4096) {
139 csr6
&= ~DMA_CONTROL_EFC
;
140 pr_debug("GMAC: disabling flow control, rxfifo too small(%d)\n",
143 csr6
|= DMA_CONTROL_EFC
;
144 csr6
|= RFA_FULL_MINUS_1K
;
145 csr6
|= RFD_FULL_MINUS_2K
;
150 static void dwmac1000_dma_operation_mode_rx(void __iomem
*ioaddr
, int mode
,
151 u32 channel
, int fifosz
, u8 qmode
)
153 u32 csr6
= readl(ioaddr
+ DMA_CONTROL
);
155 if (mode
== SF_DMA_MODE
) {
156 pr_debug("GMAC: enable RX store and forward mode\n");
157 csr6
|= DMA_CONTROL_RSF
;
159 pr_debug("GMAC: disable RX SF mode (threshold %d)\n", mode
);
160 csr6
&= ~DMA_CONTROL_RSF
;
161 csr6
&= DMA_CONTROL_TC_RX_MASK
;
163 csr6
|= DMA_CONTROL_RTC_32
;
165 csr6
|= DMA_CONTROL_RTC_64
;
167 csr6
|= DMA_CONTROL_RTC_96
;
169 csr6
|= DMA_CONTROL_RTC_128
;
172 /* Configure flow control based on rx fifo size */
173 csr6
= dwmac1000_configure_fc(csr6
, fifosz
);
175 writel(csr6
, ioaddr
+ DMA_CONTROL
);
178 static void dwmac1000_dma_operation_mode_tx(void __iomem
*ioaddr
, int mode
,
179 u32 channel
, int fifosz
, u8 qmode
)
181 u32 csr6
= readl(ioaddr
+ DMA_CONTROL
);
183 if (mode
== SF_DMA_MODE
) {
184 pr_debug("GMAC: enable TX store and forward mode\n");
185 /* Transmit COE type 2 cannot be done in cut-through mode. */
186 csr6
|= DMA_CONTROL_TSF
;
187 /* Operating on second frame increase the performance
188 * especially when transmit store-and-forward is used.
190 csr6
|= DMA_CONTROL_OSF
;
192 pr_debug("GMAC: disabling TX SF (threshold %d)\n", mode
);
193 csr6
&= ~DMA_CONTROL_TSF
;
194 csr6
&= DMA_CONTROL_TC_TX_MASK
;
195 /* Set the transmit threshold */
197 csr6
|= DMA_CONTROL_TTC_32
;
199 csr6
|= DMA_CONTROL_TTC_64
;
200 else if (mode
<= 128)
201 csr6
|= DMA_CONTROL_TTC_128
;
202 else if (mode
<= 192)
203 csr6
|= DMA_CONTROL_TTC_192
;
205 csr6
|= DMA_CONTROL_TTC_256
;
208 writel(csr6
, ioaddr
+ DMA_CONTROL
);
211 static void dwmac1000_dump_dma_regs(void __iomem
*ioaddr
, u32
*reg_space
)
215 for (i
= 0; i
< NUM_DWMAC1000_DMA_REGS
; i
++)
216 if ((i
< 12) || (i
> 17))
217 reg_space
[DMA_BUS_MODE
/ 4 + i
] =
218 readl(ioaddr
+ DMA_BUS_MODE
+ i
* 4);
221 static void dwmac1000_get_hw_feature(void __iomem
*ioaddr
,
222 struct dma_features
*dma_cap
)
224 u32 hw_cap
= readl(ioaddr
+ DMA_HW_FEATURE
);
226 dma_cap
->mbps_10_100
= (hw_cap
& DMA_HW_FEAT_MIISEL
);
227 dma_cap
->mbps_1000
= (hw_cap
& DMA_HW_FEAT_GMIISEL
) >> 1;
228 dma_cap
->half_duplex
= (hw_cap
& DMA_HW_FEAT_HDSEL
) >> 2;
229 dma_cap
->hash_filter
= (hw_cap
& DMA_HW_FEAT_HASHSEL
) >> 4;
230 dma_cap
->multi_addr
= (hw_cap
& DMA_HW_FEAT_ADDMAC
) >> 5;
231 dma_cap
->pcs
= (hw_cap
& DMA_HW_FEAT_PCSSEL
) >> 6;
232 dma_cap
->sma_mdio
= (hw_cap
& DMA_HW_FEAT_SMASEL
) >> 8;
233 dma_cap
->pmt_remote_wake_up
= (hw_cap
& DMA_HW_FEAT_RWKSEL
) >> 9;
234 dma_cap
->pmt_magic_frame
= (hw_cap
& DMA_HW_FEAT_MGKSEL
) >> 10;
236 dma_cap
->rmon
= (hw_cap
& DMA_HW_FEAT_MMCSEL
) >> 11;
238 dma_cap
->time_stamp
=
239 (hw_cap
& DMA_HW_FEAT_TSVER1SEL
) >> 12;
241 dma_cap
->atime_stamp
= (hw_cap
& DMA_HW_FEAT_TSVER2SEL
) >> 13;
242 /* 802.3az - Energy-Efficient Ethernet (EEE) */
243 dma_cap
->eee
= (hw_cap
& DMA_HW_FEAT_EEESEL
) >> 14;
244 dma_cap
->av
= (hw_cap
& DMA_HW_FEAT_AVSEL
) >> 15;
246 dma_cap
->tx_coe
= (hw_cap
& DMA_HW_FEAT_TXCOESEL
) >> 16;
247 dma_cap
->rx_coe_type1
= (hw_cap
& DMA_HW_FEAT_RXTYP1COE
) >> 17;
248 dma_cap
->rx_coe_type2
= (hw_cap
& DMA_HW_FEAT_RXTYP2COE
) >> 18;
249 dma_cap
->rxfifo_over_2048
= (hw_cap
& DMA_HW_FEAT_RXFIFOSIZE
) >> 19;
250 /* TX and RX number of channels */
251 dma_cap
->number_rx_channel
= (hw_cap
& DMA_HW_FEAT_RXCHCNT
) >> 20;
252 dma_cap
->number_tx_channel
= (hw_cap
& DMA_HW_FEAT_TXCHCNT
) >> 22;
253 /* Alternate (enhanced) DESC mode */
254 dma_cap
->enh_desc
= (hw_cap
& DMA_HW_FEAT_ENHDESSEL
) >> 24;
257 static void dwmac1000_rx_watchdog(void __iomem
*ioaddr
, u32 riwt
,
260 writel(riwt
, ioaddr
+ DMA_RX_WATCHDOG
);
263 const struct stmmac_dma_ops dwmac1000_dma_ops
= {
264 .reset
= dwmac_dma_reset
,
265 .init
= dwmac1000_dma_init
,
266 .init_rx_chan
= dwmac1000_dma_init_rx
,
267 .init_tx_chan
= dwmac1000_dma_init_tx
,
268 .axi
= dwmac1000_dma_axi
,
269 .dump_regs
= dwmac1000_dump_dma_regs
,
270 .dma_rx_mode
= dwmac1000_dma_operation_mode_rx
,
271 .dma_tx_mode
= dwmac1000_dma_operation_mode_tx
,
272 .enable_dma_transmission
= dwmac_enable_dma_transmission
,
273 .enable_dma_irq
= dwmac_enable_dma_irq
,
274 .disable_dma_irq
= dwmac_disable_dma_irq
,
275 .start_tx
= dwmac_dma_start_tx
,
276 .stop_tx
= dwmac_dma_stop_tx
,
277 .start_rx
= dwmac_dma_start_rx
,
278 .stop_rx
= dwmac_dma_stop_rx
,
279 .dma_interrupt
= dwmac_dma_interrupt
,
280 .get_hw_feature
= dwmac1000_get_hw_feature
,
281 .rx_watchdog
= dwmac1000_rx_watchdog
,