net: stmmac: xgmac: Add EEE support
authorJose Abreu <Jose.Abreu@synopsys.com>
Sat, 17 Aug 2019 18:54:49 +0000 (20:54 +0200)
committerDavid S. Miller <davem@davemloft.net>
Sat, 17 Aug 2019 19:43:59 +0000 (12:43 -0700)
Add support for EEE in XGMAC cores by implementing the necessary
callbacks.

Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c

index 3fb023953023737a81d3ff1d079a5e670514f47c..79c145ba25a82ed209560f03159ccfe43a853b8d 100644 (file)
@@ -71,6 +71,7 @@
 #define XGMAC_PSRQ(x)                  GENMASK((x) * 8 + 7, (x) * 8)
 #define XGMAC_PSRQ_SHIFT(x)            ((x) * 8)
 #define XGMAC_INT_STATUS               0x000000b0
+#define XGMAC_LPIIS                    BIT(5)
 #define XGMAC_PMTIS                    BIT(4)
 #define XGMAC_INT_EN                   0x000000b4
 #define XGMAC_TSIE                     BIT(12)
 #define XGMAC_RWKPKTEN                 BIT(2)
 #define XGMAC_MGKPKTEN                 BIT(1)
 #define XGMAC_PWRDWN                   BIT(0)
+#define XGMAC_LPI_CTRL                 0x000000d0
+#define XGMAC_TXCGE                    BIT(21)
+#define XGMAC_LPITXA                   BIT(19)
+#define XGMAC_PLS                      BIT(17)
+#define XGMAC_LPITXEN                  BIT(16)
+#define XGMAC_RLPIEX                   BIT(3)
+#define XGMAC_RLPIEN                   BIT(2)
+#define XGMAC_TLPIEX                   BIT(1)
+#define XGMAC_TLPIEN                   BIT(0)
+#define XGMAC_LPI_TIMER_CTRL           0x000000d4
 #define XGMAC_HW_FEATURE0              0x0000011c
 #define XGMAC_HWFEAT_SAVLANINS         BIT(27)
 #define XGMAC_HWFEAT_RXCOESEL          BIT(16)
 #define XGMAC_HWFEAT_TXCOESEL          BIT(14)
+#define XGMAC_HWFEAT_EEESEL            BIT(13)
 #define XGMAC_HWFEAT_TSSEL             BIT(12)
 #define XGMAC_HWFEAT_AVSEL             BIT(11)
 #define XGMAC_HWFEAT_RAVSEL            BIT(10)
index d0e7b62cc2aebc960f600976d8c605404e7df256..d8483d088711ea5237aa092f249f998dfc7ba4dd 100644 (file)
@@ -253,6 +253,7 @@ static int dwxgmac2_host_irq_status(struct mac_device_info *hw,
 {
        void __iomem *ioaddr = hw->pcsr;
        u32 stat, en;
+       int ret = 0;
 
        en = readl(ioaddr + XGMAC_INT_EN);
        stat = readl(ioaddr + XGMAC_INT_STATUS);
@@ -264,7 +265,24 @@ static int dwxgmac2_host_irq_status(struct mac_device_info *hw,
                readl(ioaddr + XGMAC_PMT);
        }
 
-       return 0;
+       if (stat & XGMAC_LPIIS) {
+               u32 lpi = readl(ioaddr + XGMAC_LPI_CTRL);
+
+               if (lpi & XGMAC_TLPIEN) {
+                       ret |= CORE_IRQ_TX_PATH_IN_LPI_MODE;
+                       x->irq_tx_path_in_lpi_mode_n++;
+               }
+               if (lpi & XGMAC_TLPIEX) {
+                       ret |= CORE_IRQ_TX_PATH_EXIT_LPI_MODE;
+                       x->irq_tx_path_exit_lpi_mode_n++;
+               }
+               if (lpi & XGMAC_RLPIEN)
+                       x->irq_rx_path_in_lpi_mode_n++;
+               if (lpi & XGMAC_RLPIEX)
+                       x->irq_rx_path_exit_lpi_mode_n++;
+       }
+
+       return ret;
 }
 
 static int dwxgmac2_host_mtl_irq_status(struct mac_device_info *hw, u32 chan)
@@ -357,6 +375,53 @@ static void dwxgmac2_get_umac_addr(struct mac_device_info *hw,
        addr[5] = (hi_addr >> 8) & 0xff;
 }
 
+static void dwxgmac2_set_eee_mode(struct mac_device_info *hw,
+                                 bool en_tx_lpi_clockgating)
+{
+       void __iomem *ioaddr = hw->pcsr;
+       u32 value;
+
+       value = readl(ioaddr + XGMAC_LPI_CTRL);
+
+       value |= XGMAC_LPITXEN | XGMAC_LPITXA;
+       if (en_tx_lpi_clockgating)
+               value |= XGMAC_TXCGE;
+
+       writel(value, ioaddr + XGMAC_LPI_CTRL);
+}
+
+static void dwxgmac2_reset_eee_mode(struct mac_device_info *hw)
+{
+       void __iomem *ioaddr = hw->pcsr;
+       u32 value;
+
+       value = readl(ioaddr + XGMAC_LPI_CTRL);
+       value &= ~(XGMAC_LPITXEN | XGMAC_LPITXA | XGMAC_TXCGE);
+       writel(value, ioaddr + XGMAC_LPI_CTRL);
+}
+
+static void dwxgmac2_set_eee_pls(struct mac_device_info *hw, int link)
+{
+       void __iomem *ioaddr = hw->pcsr;
+       u32 value;
+
+       value = readl(ioaddr + XGMAC_LPI_CTRL);
+       if (link)
+               value |= XGMAC_PLS;
+       else
+               value &= ~XGMAC_PLS;
+       writel(value, ioaddr + XGMAC_LPI_CTRL);
+}
+
+static void dwxgmac2_set_eee_timer(struct mac_device_info *hw, int ls, int tw)
+{
+       void __iomem *ioaddr = hw->pcsr;
+       u32 value;
+
+       value = (tw & 0xffff) | ((ls & 0x3ff) << 16);
+       writel(value, ioaddr + XGMAC_LPI_TIMER_CTRL);
+}
+
 static void dwxgmac2_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits,
                                int mcbitslog2)
 {
@@ -1105,10 +1170,10 @@ const struct stmmac_ops dwxgmac210_ops = {
        .pmt = dwxgmac2_pmt,
        .set_umac_addr = dwxgmac2_set_umac_addr,
        .get_umac_addr = dwxgmac2_get_umac_addr,
-       .set_eee_mode = NULL,
-       .reset_eee_mode = NULL,
-       .set_eee_timer = NULL,
-       .set_eee_pls = NULL,
+       .set_eee_mode = dwxgmac2_set_eee_mode,
+       .reset_eee_mode = dwxgmac2_reset_eee_mode,
+       .set_eee_timer = dwxgmac2_set_eee_timer,
+       .set_eee_pls = dwxgmac2_set_eee_pls,
        .pcs_ctrl_ane = NULL,
        .pcs_rane = NULL,
        .pcs_get_adv_lp = NULL,
index 42c13d14420303f3dff5e8b75171cb532832c36f..f2d5901fbaff519369dc292c3f953f89267feb48 100644 (file)
@@ -361,6 +361,7 @@ static void dwxgmac2_get_hw_feature(void __iomem *ioaddr,
        hw_cap = readl(ioaddr + XGMAC_HW_FEATURE0);
        dma_cap->rx_coe = (hw_cap & XGMAC_HWFEAT_RXCOESEL) >> 16;
        dma_cap->tx_coe = (hw_cap & XGMAC_HWFEAT_TXCOESEL) >> 14;
+       dma_cap->eee = (hw_cap & XGMAC_HWFEAT_EEESEL) >> 13;
        dma_cap->atime_stamp = (hw_cap & XGMAC_HWFEAT_TSSEL) >> 12;
        dma_cap->av = (hw_cap & XGMAC_HWFEAT_AVSEL) >> 11;
        dma_cap->av &= (hw_cap & XGMAC_HWFEAT_RAVSEL) >> 10;