linux/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
<<
>>
Prefs
   1/*
   2 * This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
   3 * DWC Ether MAC version 4.xx  has been used for  developing this code.
   4 *
   5 * This contains the functions to handle the dma.
   6 *
   7 * Copyright (C) 2015  STMicroelectronics Ltd
   8 *
   9 * This program is free software; you can redistribute it and/or modify it
  10 * under the terms and conditions of the GNU General Public License,
  11 * version 2, as published by the Free Software Foundation.
  12 *
  13 * Author: Alexandre Torgue <alexandre.torgue@st.com>
  14 */
  15
  16#include <linux/io.h>
  17#include "dwmac4.h"
  18#include "dwmac4_dma.h"
  19
  20static void dwmac4_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
  21{
  22        u32 value = readl(ioaddr + DMA_SYS_BUS_MODE);
  23        int i;
  24
  25        pr_info("dwmac4: Master AXI performs %s burst length\n",
  26                (value & DMA_SYS_BUS_FB) ? "fixed" : "any");
  27
  28        if (axi->axi_lpi_en)
  29                value |= DMA_AXI_EN_LPI;
  30        if (axi->axi_xit_frm)
  31                value |= DMA_AXI_LPI_XIT_FRM;
  32
  33        value &= ~DMA_AXI_WR_OSR_LMT;
  34        value |= (axi->axi_wr_osr_lmt & DMA_AXI_OSR_MAX) <<
  35                 DMA_AXI_WR_OSR_LMT_SHIFT;
  36
  37        value &= ~DMA_AXI_RD_OSR_LMT;
  38        value |= (axi->axi_rd_osr_lmt & DMA_AXI_OSR_MAX) <<
  39                 DMA_AXI_RD_OSR_LMT_SHIFT;
  40
  41        /* Depending on the UNDEF bit the Master AXI will perform any burst
  42         * length according to the BLEN programmed (by default all BLEN are
  43         * set).
  44         */
  45        for (i = 0; i < AXI_BLEN; i++) {
  46                switch (axi->axi_blen[i]) {
  47                case 256:
  48                        value |= DMA_AXI_BLEN256;
  49                        break;
  50                case 128:
  51                        value |= DMA_AXI_BLEN128;
  52                        break;
  53                case 64:
  54                        value |= DMA_AXI_BLEN64;
  55                        break;
  56                case 32:
  57                        value |= DMA_AXI_BLEN32;
  58                        break;
  59                case 16:
  60                        value |= DMA_AXI_BLEN16;
  61                        break;
  62                case 8:
  63                        value |= DMA_AXI_BLEN8;
  64                        break;
  65                case 4:
  66                        value |= DMA_AXI_BLEN4;
  67                        break;
  68                }
  69        }
  70
  71        writel(value, ioaddr + DMA_SYS_BUS_MODE);
  72}
  73
  74static void dwmac4_dma_init_channel(void __iomem *ioaddr, int pbl,
  75                                    u32 dma_tx_phy, u32 dma_rx_phy,
  76                                    u32 channel)
  77{
  78        u32 value;
  79
  80        /* set PBL for each channels. Currently we affect same configuration
  81         * on each channel
  82         */
  83        value = readl(ioaddr + DMA_CHAN_CONTROL(channel));
  84        value = value | DMA_BUS_MODE_PBL;
  85        writel(value, ioaddr + DMA_CHAN_CONTROL(channel));
  86
  87        value = readl(ioaddr + DMA_CHAN_TX_CONTROL(channel));
  88        value = value | (pbl << DMA_BUS_MODE_PBL_SHIFT);
  89        writel(value, ioaddr + DMA_CHAN_TX_CONTROL(channel));
  90
  91        value = readl(ioaddr + DMA_CHAN_RX_CONTROL(channel));
  92        value = value | (pbl << DMA_BUS_MODE_RPBL_SHIFT);
  93        writel(value, ioaddr + DMA_CHAN_RX_CONTROL(channel));
  94
  95        /* Mask interrupts by writing to CSR7 */
  96        writel(DMA_CHAN_INTR_DEFAULT_MASK, ioaddr + DMA_CHAN_INTR_ENA(channel));
  97
  98        writel(dma_tx_phy, ioaddr + DMA_CHAN_TX_BASE_ADDR(channel));
  99        writel(dma_rx_phy, ioaddr + DMA_CHAN_RX_BASE_ADDR(channel));
 100}
 101
 102static void dwmac4_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb,
 103                            int aal, u32 dma_tx, u32 dma_rx, int atds)
 104{
 105        u32 value = readl(ioaddr + DMA_SYS_BUS_MODE);
 106        int i;
 107
 108        /* Set the Fixed burst mode */
 109        if (fb)
 110                value |= DMA_SYS_BUS_FB;
 111
 112        /* Mixed Burst has no effect when fb is set */
 113        if (mb)
 114                value |= DMA_SYS_BUS_MB;
 115
 116        if (aal)
 117                value |= DMA_SYS_BUS_AAL;
 118
 119        writel(value, ioaddr + DMA_SYS_BUS_MODE);
 120
 121        for (i = 0; i < DMA_CHANNEL_NB_MAX; i++)
 122                dwmac4_dma_init_channel(ioaddr, pbl, dma_tx, dma_rx, i);
 123}
 124
 125static void _dwmac4_dump_dma_regs(void __iomem *ioaddr, u32 channel)
 126{
 127        pr_debug(" Channel %d\n", channel);
 128        pr_debug("\tDMA_CHAN_CONTROL, offset: 0x%x, val: 0x%x\n", 0,
 129                 readl(ioaddr + DMA_CHAN_CONTROL(channel)));
 130        pr_debug("\tDMA_CHAN_TX_CONTROL, offset: 0x%x, val: 0x%x\n", 0x4,
 131                 readl(ioaddr + DMA_CHAN_TX_CONTROL(channel)));
 132        pr_debug("\tDMA_CHAN_RX_CONTROL, offset: 0x%x, val: 0x%x\n", 0x8,
 133                 readl(ioaddr + DMA_CHAN_RX_CONTROL(channel)));
 134        pr_debug("\tDMA_CHAN_TX_BASE_ADDR, offset: 0x%x, val: 0x%x\n", 0x14,
 135                 readl(ioaddr + DMA_CHAN_TX_BASE_ADDR(channel)));
 136        pr_debug("\tDMA_CHAN_RX_BASE_ADDR, offset: 0x%x, val: 0x%x\n", 0x1c,
 137                 readl(ioaddr + DMA_CHAN_RX_BASE_ADDR(channel)));
 138        pr_debug("\tDMA_CHAN_TX_END_ADDR, offset: 0x%x, val: 0x%x\n", 0x20,
 139                 readl(ioaddr + DMA_CHAN_TX_END_ADDR(channel)));
 140        pr_debug("\tDMA_CHAN_RX_END_ADDR, offset: 0x%x, val: 0x%x\n", 0x28,
 141                 readl(ioaddr + DMA_CHAN_RX_END_ADDR(channel)));
 142        pr_debug("\tDMA_CHAN_TX_RING_LEN, offset: 0x%x, val: 0x%x\n", 0x2c,
 143                 readl(ioaddr + DMA_CHAN_TX_RING_LEN(channel)));
 144        pr_debug("\tDMA_CHAN_RX_RING_LEN, offset: 0x%x, val: 0x%x\n", 0x30,
 145                 readl(ioaddr + DMA_CHAN_RX_RING_LEN(channel)));
 146        pr_debug("\tDMA_CHAN_INTR_ENA, offset: 0x%x, val: 0x%x\n", 0x34,
 147                 readl(ioaddr + DMA_CHAN_INTR_ENA(channel)));
 148        pr_debug("\tDMA_CHAN_RX_WATCHDOG, offset: 0x%x, val: 0x%x\n", 0x38,
 149                 readl(ioaddr + DMA_CHAN_RX_WATCHDOG(channel)));
 150        pr_debug("\tDMA_CHAN_SLOT_CTRL_STATUS, offset: 0x%x, val: 0x%x\n", 0x3c,
 151                 readl(ioaddr + DMA_CHAN_SLOT_CTRL_STATUS(channel)));
 152        pr_debug("\tDMA_CHAN_CUR_TX_DESC, offset: 0x%x, val: 0x%x\n", 0x44,
 153                 readl(ioaddr + DMA_CHAN_CUR_TX_DESC(channel)));
 154        pr_debug("\tDMA_CHAN_CUR_RX_DESC, offset: 0x%x, val: 0x%x\n", 0x4c,
 155                 readl(ioaddr + DMA_CHAN_CUR_RX_DESC(channel)));
 156        pr_debug("\tDMA_CHAN_CUR_TX_BUF_ADDR, offset: 0x%x, val: 0x%x\n", 0x54,
 157                 readl(ioaddr + DMA_CHAN_CUR_TX_BUF_ADDR(channel)));
 158        pr_debug("\tDMA_CHAN_CUR_RX_BUF_ADDR, offset: 0x%x, val: 0x%x\n", 0x5c,
 159                 readl(ioaddr + DMA_CHAN_CUR_RX_BUF_ADDR(channel)));
 160        pr_debug("\tDMA_CHAN_STATUS, offset: 0x%x, val: 0x%x\n", 0x60,
 161                 readl(ioaddr + DMA_CHAN_STATUS(channel)));
 162}
 163
 164static void dwmac4_dump_dma_regs(void __iomem *ioaddr)
 165{
 166        int i;
 167
 168        pr_debug(" GMAC4 DMA registers\n");
 169
 170        for (i = 0; i < DMA_CHANNEL_NB_MAX; i++)
 171                _dwmac4_dump_dma_regs(ioaddr, i);
 172}
 173
 174static void dwmac4_rx_watchdog(void __iomem *ioaddr, u32 riwt)
 175{
 176        int i;
 177
 178        for (i = 0; i < DMA_CHANNEL_NB_MAX; i++)
 179                writel(riwt, ioaddr + DMA_CHAN_RX_WATCHDOG(i));
 180}
 181
 182static void dwmac4_dma_chan_op_mode(void __iomem *ioaddr, int txmode,
 183                                    int rxmode, u32 channel)
 184{
 185        u32 mtl_tx_op, mtl_rx_op, mtl_rx_int;
 186
 187        /* Following code only done for channel 0, other channels not yet
 188         * supported.
 189         */
 190        mtl_tx_op = readl(ioaddr + MTL_CHAN_TX_OP_MODE(channel));
 191
 192        if (txmode == SF_DMA_MODE) {
 193                pr_debug("GMAC: enable TX store and forward mode\n");
 194                /* Transmit COE type 2 cannot be done in cut-through mode. */
 195                mtl_tx_op |= MTL_OP_MODE_TSF;
 196        } else {
 197                pr_debug("GMAC: disabling TX SF (threshold %d)\n", txmode);
 198                mtl_tx_op &= ~MTL_OP_MODE_TSF;
 199                mtl_tx_op &= MTL_OP_MODE_TTC_MASK;
 200                /* Set the transmit threshold */
 201                if (txmode <= 32)
 202                        mtl_tx_op |= MTL_OP_MODE_TTC_32;
 203                else if (txmode <= 64)
 204                        mtl_tx_op |= MTL_OP_MODE_TTC_64;
 205                else if (txmode <= 96)
 206                        mtl_tx_op |= MTL_OP_MODE_TTC_96;
 207                else if (txmode <= 128)
 208                        mtl_tx_op |= MTL_OP_MODE_TTC_128;
 209                else if (txmode <= 192)
 210                        mtl_tx_op |= MTL_OP_MODE_TTC_192;
 211                else if (txmode <= 256)
 212                        mtl_tx_op |= MTL_OP_MODE_TTC_256;
 213                else if (txmode <= 384)
 214                        mtl_tx_op |= MTL_OP_MODE_TTC_384;
 215                else
 216                        mtl_tx_op |= MTL_OP_MODE_TTC_512;
 217        }
 218
 219        writel(mtl_tx_op, ioaddr +  MTL_CHAN_TX_OP_MODE(channel));
 220
 221        mtl_rx_op = readl(ioaddr + MTL_CHAN_RX_OP_MODE(channel));
 222
 223        if (rxmode == SF_DMA_MODE) {
 224                pr_debug("GMAC: enable RX store and forward mode\n");
 225                mtl_rx_op |= MTL_OP_MODE_RSF;
 226        } else {
 227                pr_debug("GMAC: disable RX SF mode (threshold %d)\n", rxmode);
 228                mtl_rx_op &= ~MTL_OP_MODE_RSF;
 229                mtl_rx_op &= MTL_OP_MODE_RTC_MASK;
 230                if (rxmode <= 32)
 231                        mtl_rx_op |= MTL_OP_MODE_RTC_32;
 232                else if (rxmode <= 64)
 233                        mtl_rx_op |= MTL_OP_MODE_RTC_64;
 234                else if (rxmode <= 96)
 235                        mtl_rx_op |= MTL_OP_MODE_RTC_96;
 236                else
 237                        mtl_rx_op |= MTL_OP_MODE_RTC_128;
 238        }
 239
 240        writel(mtl_rx_op, ioaddr + MTL_CHAN_RX_OP_MODE(channel));
 241
 242        /* Enable MTL RX overflow */
 243        mtl_rx_int = readl(ioaddr + MTL_CHAN_INT_CTRL(channel));
 244        writel(mtl_rx_int | MTL_RX_OVERFLOW_INT_EN,
 245               ioaddr + MTL_CHAN_INT_CTRL(channel));
 246}
 247
 248static void dwmac4_dma_operation_mode(void __iomem *ioaddr, int txmode,
 249                                      int rxmode, int rxfifosz)
 250{
 251        /* Only Channel 0 is actually configured and used */
 252        dwmac4_dma_chan_op_mode(ioaddr, txmode, rxmode, 0);
 253}
 254
 255static void dwmac4_get_hw_feature(void __iomem *ioaddr,
 256                                  struct dma_features *dma_cap)
 257{
 258        u32 hw_cap = readl(ioaddr + GMAC_HW_FEATURE0);
 259
 260        /*  MAC HW feature0 */
 261        dma_cap->mbps_10_100 = (hw_cap & GMAC_HW_FEAT_MIISEL);
 262        dma_cap->mbps_1000 = (hw_cap & GMAC_HW_FEAT_GMIISEL) >> 1;
 263        dma_cap->half_duplex = (hw_cap & GMAC_HW_FEAT_HDSEL) >> 2;
 264        dma_cap->hash_filter = (hw_cap & GMAC_HW_FEAT_VLHASH) >> 4;
 265        dma_cap->multi_addr = (hw_cap & GMAC_HW_FEAT_ADDMAC) >> 18;
 266        dma_cap->pcs = (hw_cap & GMAC_HW_FEAT_PCSSEL) >> 3;
 267        dma_cap->sma_mdio = (hw_cap & GMAC_HW_FEAT_SMASEL) >> 5;
 268        dma_cap->pmt_remote_wake_up = (hw_cap & GMAC_HW_FEAT_RWKSEL) >> 6;
 269        dma_cap->pmt_magic_frame = (hw_cap & GMAC_HW_FEAT_MGKSEL) >> 7;
 270        /* MMC */
 271        dma_cap->rmon = (hw_cap & GMAC_HW_FEAT_MMCSEL) >> 8;
 272        /* IEEE 1588-2008 */
 273        dma_cap->atime_stamp = (hw_cap & GMAC_HW_FEAT_TSSEL) >> 12;
 274        /* 802.3az - Energy-Efficient Ethernet (EEE) */
 275        dma_cap->eee = (hw_cap & GMAC_HW_FEAT_EEESEL) >> 13;
 276        /* TX and RX csum */
 277        dma_cap->tx_coe = (hw_cap & GMAC_HW_FEAT_TXCOSEL) >> 14;
 278        dma_cap->rx_coe =  (hw_cap & GMAC_HW_FEAT_RXCOESEL) >> 16;
 279
 280        /* MAC HW feature1 */
 281        hw_cap = readl(ioaddr + GMAC_HW_FEATURE1);
 282        dma_cap->av = (hw_cap & GMAC_HW_FEAT_AVSEL) >> 20;
 283        dma_cap->tsoen = (hw_cap & GMAC_HW_TSOEN) >> 18;
 284        /* MAC HW feature2 */
 285        hw_cap = readl(ioaddr + GMAC_HW_FEATURE2);
 286        /* TX and RX number of channels */
 287        dma_cap->number_rx_channel =
 288                ((hw_cap & GMAC_HW_FEAT_RXCHCNT) >> 12) + 1;
 289        dma_cap->number_tx_channel =
 290                ((hw_cap & GMAC_HW_FEAT_TXCHCNT) >> 18) + 1;
 291
 292        /* IEEE 1588-2002 */
 293        dma_cap->time_stamp = 0;
 294}
 295
 296/* Enable/disable TSO feature and set MSS */
 297static void dwmac4_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
 298{
 299        u32 value;
 300
 301        if (en) {
 302                /* enable TSO */
 303                value = readl(ioaddr + DMA_CHAN_TX_CONTROL(chan));
 304                writel(value | DMA_CONTROL_TSE,
 305                       ioaddr + DMA_CHAN_TX_CONTROL(chan));
 306        } else {
 307                /* enable TSO */
 308                value = readl(ioaddr + DMA_CHAN_TX_CONTROL(chan));
 309                writel(value & ~DMA_CONTROL_TSE,
 310                       ioaddr + DMA_CHAN_TX_CONTROL(chan));
 311        }
 312}
 313
 314const struct stmmac_dma_ops dwmac4_dma_ops = {
 315        .reset = dwmac4_dma_reset,
 316        .init = dwmac4_dma_init,
 317        .axi = dwmac4_dma_axi,
 318        .dump_regs = dwmac4_dump_dma_regs,
 319        .dma_mode = dwmac4_dma_operation_mode,
 320        .enable_dma_irq = dwmac4_enable_dma_irq,
 321        .disable_dma_irq = dwmac4_disable_dma_irq,
 322        .start_tx = dwmac4_dma_start_tx,
 323        .stop_tx = dwmac4_dma_stop_tx,
 324        .start_rx = dwmac4_dma_start_rx,
 325        .stop_rx = dwmac4_dma_stop_rx,
 326        .dma_interrupt = dwmac4_dma_interrupt,
 327        .get_hw_feature = dwmac4_get_hw_feature,
 328        .rx_watchdog = dwmac4_rx_watchdog,
 329        .set_rx_ring_len = dwmac4_set_rx_ring_len,
 330        .set_tx_ring_len = dwmac4_set_tx_ring_len,
 331        .set_rx_tail_ptr = dwmac4_set_rx_tail_ptr,
 332        .set_tx_tail_ptr = dwmac4_set_tx_tail_ptr,
 333        .enable_tso = dwmac4_enable_tso,
 334};
 335
 336const struct stmmac_dma_ops dwmac410_dma_ops = {
 337        .reset = dwmac4_dma_reset,
 338        .init = dwmac4_dma_init,
 339        .axi = dwmac4_dma_axi,
 340        .dump_regs = dwmac4_dump_dma_regs,
 341        .dma_mode = dwmac4_dma_operation_mode,
 342        .enable_dma_irq = dwmac410_enable_dma_irq,
 343        .disable_dma_irq = dwmac4_disable_dma_irq,
 344        .start_tx = dwmac4_dma_start_tx,
 345        .stop_tx = dwmac4_dma_stop_tx,
 346        .start_rx = dwmac4_dma_start_rx,
 347        .stop_rx = dwmac4_dma_stop_rx,
 348        .dma_interrupt = dwmac4_dma_interrupt,
 349        .get_hw_feature = dwmac4_get_hw_feature,
 350        .rx_watchdog = dwmac4_rx_watchdog,
 351        .set_rx_ring_len = dwmac4_set_rx_ring_len,
 352        .set_tx_ring_len = dwmac4_set_tx_ring_len,
 353        .set_rx_tail_ptr = dwmac4_set_rx_tail_ptr,
 354        .set_tx_tail_ptr = dwmac4_set_tx_tail_ptr,
 355        .enable_tso = dwmac4_enable_tso,
 356};
 357