Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2007-2015  STMicroelectronics Ltd
0004  *
0005  * Author: Alexandre Torgue <alexandre.torgue@st.com>
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     /* DMA SW reset */
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     /* ABNORMAL interrupts */
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     /* TX/RX NORMAL interrupts */
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     /* For MAC Addr registers se have to set the Address Enable (AE)
0197      * bit that has no effect on the High Reg 0 where the bit 31 (MO)
0198      * is RO.
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 /* Enable disable MAC RX/TX */
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     /* Read the MAC address from the hardware */
0225     hi_addr = readl(ioaddr + high);
0226     lo_addr = readl(ioaddr + low);
0227 
0228     /* Extract the MAC address from the high and low words */
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 }