0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/io.h>
0009 #include <linux/iopoll.h>
0010 #include <linux/delay.h>
0011 #include "common.h"
0012 #include "dwmac4_dma.h"
0013 #include "dwmac4.h"
0014
0015 int dwmac4_dma_reset(void __iomem *ioaddr)
0016 {
0017 u32 value = readl(ioaddr + DMA_BUS_MODE);
0018
0019
0020 value |= DMA_BUS_MODE_SFT_RESET;
0021 writel(value, ioaddr + DMA_BUS_MODE);
0022
0023 return readl_poll_timeout(ioaddr + DMA_BUS_MODE, value,
0024 !(value & DMA_BUS_MODE_SFT_RESET),
0025 10000, 1000000);
0026 }
0027
0028 void dwmac4_set_rx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan)
0029 {
0030 writel(tail_ptr, ioaddr + DMA_CHAN_RX_END_ADDR(chan));
0031 }
0032
0033 void dwmac4_set_tx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan)
0034 {
0035 writel(tail_ptr, ioaddr + DMA_CHAN_TX_END_ADDR(chan));
0036 }
0037
0038 void dwmac4_dma_start_tx(void __iomem *ioaddr, u32 chan)
0039 {
0040 u32 value = readl(ioaddr + DMA_CHAN_TX_CONTROL(chan));
0041
0042 value |= DMA_CONTROL_ST;
0043 writel(value, ioaddr + DMA_CHAN_TX_CONTROL(chan));
0044
0045 value = readl(ioaddr + GMAC_CONFIG);
0046 value |= GMAC_CONFIG_TE;
0047 writel(value, ioaddr + GMAC_CONFIG);
0048 }
0049
0050 void dwmac4_dma_stop_tx(void __iomem *ioaddr, u32 chan)
0051 {
0052 u32 value = readl(ioaddr + DMA_CHAN_TX_CONTROL(chan));
0053
0054 value &= ~DMA_CONTROL_ST;
0055 writel(value, ioaddr + DMA_CHAN_TX_CONTROL(chan));
0056 }
0057
0058 void dwmac4_dma_start_rx(void __iomem *ioaddr, u32 chan)
0059 {
0060 u32 value = readl(ioaddr + DMA_CHAN_RX_CONTROL(chan));
0061
0062 value |= DMA_CONTROL_SR;
0063
0064 writel(value, ioaddr + DMA_CHAN_RX_CONTROL(chan));
0065
0066 value = readl(ioaddr + GMAC_CONFIG);
0067 value |= GMAC_CONFIG_RE;
0068 writel(value, ioaddr + GMAC_CONFIG);
0069 }
0070
0071 void dwmac4_dma_stop_rx(void __iomem *ioaddr, u32 chan)
0072 {
0073 u32 value = readl(ioaddr + DMA_CHAN_RX_CONTROL(chan));
0074
0075 value &= ~DMA_CONTROL_SR;
0076 writel(value, ioaddr + DMA_CHAN_RX_CONTROL(chan));
0077 }
0078
0079 void dwmac4_set_tx_ring_len(void __iomem *ioaddr, u32 len, u32 chan)
0080 {
0081 writel(len, ioaddr + DMA_CHAN_TX_RING_LEN(chan));
0082 }
0083
0084 void dwmac4_set_rx_ring_len(void __iomem *ioaddr, u32 len, u32 chan)
0085 {
0086 writel(len, ioaddr + DMA_CHAN_RX_RING_LEN(chan));
0087 }
0088
0089 void dwmac4_enable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx)
0090 {
0091 u32 value = readl(ioaddr + DMA_CHAN_INTR_ENA(chan));
0092
0093 if (rx)
0094 value |= DMA_CHAN_INTR_DEFAULT_RX;
0095 if (tx)
0096 value |= DMA_CHAN_INTR_DEFAULT_TX;
0097
0098 writel(value, ioaddr + DMA_CHAN_INTR_ENA(chan));
0099 }
0100
0101 void dwmac410_enable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx)
0102 {
0103 u32 value = readl(ioaddr + DMA_CHAN_INTR_ENA(chan));
0104
0105 if (rx)
0106 value |= DMA_CHAN_INTR_DEFAULT_RX_4_10;
0107 if (tx)
0108 value |= DMA_CHAN_INTR_DEFAULT_TX_4_10;
0109
0110 writel(value, ioaddr + DMA_CHAN_INTR_ENA(chan));
0111 }
0112
0113 void dwmac4_disable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx)
0114 {
0115 u32 value = readl(ioaddr + DMA_CHAN_INTR_ENA(chan));
0116
0117 if (rx)
0118 value &= ~DMA_CHAN_INTR_DEFAULT_RX;
0119 if (tx)
0120 value &= ~DMA_CHAN_INTR_DEFAULT_TX;
0121
0122 writel(value, ioaddr + DMA_CHAN_INTR_ENA(chan));
0123 }
0124
0125 void dwmac410_disable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx)
0126 {
0127 u32 value = readl(ioaddr + DMA_CHAN_INTR_ENA(chan));
0128
0129 if (rx)
0130 value &= ~DMA_CHAN_INTR_DEFAULT_RX_4_10;
0131 if (tx)
0132 value &= ~DMA_CHAN_INTR_DEFAULT_TX_4_10;
0133
0134 writel(value, ioaddr + DMA_CHAN_INTR_ENA(chan));
0135 }
0136
0137 int dwmac4_dma_interrupt(void __iomem *ioaddr,
0138 struct stmmac_extra_stats *x, u32 chan, u32 dir)
0139 {
0140 u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(chan));
0141 u32 intr_en = readl(ioaddr + DMA_CHAN_INTR_ENA(chan));
0142 int ret = 0;
0143
0144 if (dir == DMA_DIR_RX)
0145 intr_status &= DMA_CHAN_STATUS_MSK_RX;
0146 else if (dir == DMA_DIR_TX)
0147 intr_status &= DMA_CHAN_STATUS_MSK_TX;
0148
0149
0150 if (unlikely(intr_status & DMA_CHAN_STATUS_AIS)) {
0151 if (unlikely(intr_status & DMA_CHAN_STATUS_RBU))
0152 x->rx_buf_unav_irq++;
0153 if (unlikely(intr_status & DMA_CHAN_STATUS_RPS))
0154 x->rx_process_stopped_irq++;
0155 if (unlikely(intr_status & DMA_CHAN_STATUS_RWT))
0156 x->rx_watchdog_irq++;
0157 if (unlikely(intr_status & DMA_CHAN_STATUS_ETI))
0158 x->tx_early_irq++;
0159 if (unlikely(intr_status & DMA_CHAN_STATUS_TPS)) {
0160 x->tx_process_stopped_irq++;
0161 ret = tx_hard_error;
0162 }
0163 if (unlikely(intr_status & DMA_CHAN_STATUS_FBE)) {
0164 x->fatal_bus_error_irq++;
0165 ret = tx_hard_error;
0166 }
0167 }
0168
0169 if (likely(intr_status & DMA_CHAN_STATUS_NIS))
0170 x->normal_irq_n++;
0171 if (likely(intr_status & DMA_CHAN_STATUS_RI)) {
0172 x->rx_normal_irq_n++;
0173 x->rxq_stats[chan].rx_normal_irq_n++;
0174 ret |= handle_rx;
0175 }
0176 if (likely(intr_status & DMA_CHAN_STATUS_TI)) {
0177 x->tx_normal_irq_n++;
0178 x->txq_stats[chan].tx_normal_irq_n++;
0179 ret |= handle_tx;
0180 }
0181 if (unlikely(intr_status & DMA_CHAN_STATUS_TBU))
0182 ret |= handle_tx;
0183 if (unlikely(intr_status & DMA_CHAN_STATUS_ERI))
0184 x->rx_early_irq++;
0185
0186 writel(intr_status & intr_en, ioaddr + DMA_CHAN_STATUS(chan));
0187 return ret;
0188 }
0189
0190 void stmmac_dwmac4_set_mac_addr(void __iomem *ioaddr, const u8 addr[6],
0191 unsigned int high, unsigned int low)
0192 {
0193 unsigned long data;
0194
0195 data = (addr[5] << 8) | addr[4];
0196
0197
0198
0199
0200 data |= (STMMAC_CHAN0 << GMAC_HI_DCS_SHIFT);
0201 writel(data | GMAC_HI_REG_AE, ioaddr + high);
0202 data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
0203 writel(data, ioaddr + low);
0204 }
0205
0206
0207 void stmmac_dwmac4_set_mac(void __iomem *ioaddr, bool enable)
0208 {
0209 u32 value = readl(ioaddr + GMAC_CONFIG);
0210
0211 if (enable)
0212 value |= GMAC_CONFIG_RE | GMAC_CONFIG_TE;
0213 else
0214 value &= ~(GMAC_CONFIG_TE | GMAC_CONFIG_RE);
0215
0216 writel(value, ioaddr + GMAC_CONFIG);
0217 }
0218
0219 void stmmac_dwmac4_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
0220 unsigned int high, unsigned int low)
0221 {
0222 unsigned int hi_addr, lo_addr;
0223
0224
0225 hi_addr = readl(ioaddr + high);
0226 lo_addr = readl(ioaddr + low);
0227
0228
0229 addr[0] = lo_addr & 0xff;
0230 addr[1] = (lo_addr >> 8) & 0xff;
0231 addr[2] = (lo_addr >> 16) & 0xff;
0232 addr[3] = (lo_addr >> 24) & 0xff;
0233 addr[4] = hi_addr & 0xff;
0234 addr[5] = (hi_addr >> 8) & 0xff;
0235 }