Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * dwmac-sun8i.c - Allwinner sun8i DWMAC specific glue layer
0004  *
0005  * Copyright (C) 2017 Corentin Labbe <clabbe.montjoie@gmail.com>
0006  */
0007 
0008 #include <linux/clk.h>
0009 #include <linux/io.h>
0010 #include <linux/iopoll.h>
0011 #include <linux/mdio-mux.h>
0012 #include <linux/mfd/syscon.h>
0013 #include <linux/module.h>
0014 #include <linux/of_device.h>
0015 #include <linux/of_mdio.h>
0016 #include <linux/of_net.h>
0017 #include <linux/phy.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/pm_runtime.h>
0020 #include <linux/regulator/consumer.h>
0021 #include <linux/regmap.h>
0022 #include <linux/stmmac.h>
0023 
0024 #include "stmmac.h"
0025 #include "stmmac_platform.h"
0026 
0027 /* General notes on dwmac-sun8i:
0028  * Locking: no locking is necessary in this file because all necessary locking
0029  *      is done in the "stmmac files"
0030  */
0031 
0032 /* struct emac_variant - Describe dwmac-sun8i hardware variant
0033  * @default_syscon_value:   The default value of the EMAC register in syscon
0034  *              This value is used for disabling properly EMAC
0035  *              and used as a good starting value in case of the
0036  *              boot process(uboot) leave some stuff.
0037  * @syscon_field        reg_field for the syscon's gmac register
0038  * @soc_has_internal_phy:   Does the MAC embed an internal PHY
0039  * @support_mii:        Does the MAC handle MII
0040  * @support_rmii:       Does the MAC handle RMII
0041  * @support_rgmii:      Does the MAC handle RGMII
0042  *
0043  * @rx_delay_max:       Maximum raw value for RX delay chain
0044  * @tx_delay_max:       Maximum raw value for TX delay chain
0045  *              These two also indicate the bitmask for
0046  *              the RX and TX delay chain registers. A
0047  *              value of zero indicates this is not supported.
0048  */
0049 struct emac_variant {
0050     u32 default_syscon_value;
0051     const struct reg_field *syscon_field;
0052     bool soc_has_internal_phy;
0053     bool support_mii;
0054     bool support_rmii;
0055     bool support_rgmii;
0056     u8 rx_delay_max;
0057     u8 tx_delay_max;
0058 };
0059 
0060 /* struct sunxi_priv_data - hold all sunxi private data
0061  * @ephy_clk:   reference to the optional EPHY clock for the internal PHY
0062  * @regulator:  reference to the optional regulator
0063  * @rst_ephy:   reference to the optional EPHY reset for the internal PHY
0064  * @variant:    reference to the current board variant
0065  * @regmap: regmap for using the syscon
0066  * @internal_phy_powered: Does the internal PHY is enabled
0067  * @use_internal_phy: Is the internal PHY selected for use
0068  * @mux_handle: Internal pointer used by mdio-mux lib
0069  */
0070 struct sunxi_priv_data {
0071     struct clk *ephy_clk;
0072     struct regulator *regulator;
0073     struct reset_control *rst_ephy;
0074     const struct emac_variant *variant;
0075     struct regmap_field *regmap_field;
0076     bool internal_phy_powered;
0077     bool use_internal_phy;
0078     void *mux_handle;
0079 };
0080 
0081 /* EMAC clock register @ 0x30 in the "system control" address range */
0082 static const struct reg_field sun8i_syscon_reg_field = {
0083     .reg = 0x30,
0084     .lsb = 0,
0085     .msb = 31,
0086 };
0087 
0088 /* EMAC clock register @ 0x164 in the CCU address range */
0089 static const struct reg_field sun8i_ccu_reg_field = {
0090     .reg = 0x164,
0091     .lsb = 0,
0092     .msb = 31,
0093 };
0094 
0095 static const struct emac_variant emac_variant_h3 = {
0096     .default_syscon_value = 0x58000,
0097     .syscon_field = &sun8i_syscon_reg_field,
0098     .soc_has_internal_phy = true,
0099     .support_mii = true,
0100     .support_rmii = true,
0101     .support_rgmii = true,
0102     .rx_delay_max = 31,
0103     .tx_delay_max = 7,
0104 };
0105 
0106 static const struct emac_variant emac_variant_v3s = {
0107     .default_syscon_value = 0x38000,
0108     .syscon_field = &sun8i_syscon_reg_field,
0109     .soc_has_internal_phy = true,
0110     .support_mii = true
0111 };
0112 
0113 static const struct emac_variant emac_variant_a83t = {
0114     .default_syscon_value = 0,
0115     .syscon_field = &sun8i_syscon_reg_field,
0116     .soc_has_internal_phy = false,
0117     .support_mii = true,
0118     .support_rgmii = true,
0119     .rx_delay_max = 31,
0120     .tx_delay_max = 7,
0121 };
0122 
0123 static const struct emac_variant emac_variant_r40 = {
0124     .default_syscon_value = 0,
0125     .syscon_field = &sun8i_ccu_reg_field,
0126     .support_mii = true,
0127     .support_rgmii = true,
0128     .rx_delay_max = 7,
0129 };
0130 
0131 static const struct emac_variant emac_variant_a64 = {
0132     .default_syscon_value = 0,
0133     .syscon_field = &sun8i_syscon_reg_field,
0134     .soc_has_internal_phy = false,
0135     .support_mii = true,
0136     .support_rmii = true,
0137     .support_rgmii = true,
0138     .rx_delay_max = 31,
0139     .tx_delay_max = 7,
0140 };
0141 
0142 static const struct emac_variant emac_variant_h6 = {
0143     .default_syscon_value = 0x50000,
0144     .syscon_field = &sun8i_syscon_reg_field,
0145     /* The "Internal PHY" of H6 is not on the die. It's on the
0146      * co-packaged AC200 chip instead.
0147      */
0148     .soc_has_internal_phy = false,
0149     .support_mii = true,
0150     .support_rmii = true,
0151     .support_rgmii = true,
0152     .rx_delay_max = 31,
0153     .tx_delay_max = 7,
0154 };
0155 
0156 #define EMAC_BASIC_CTL0 0x00
0157 #define EMAC_BASIC_CTL1 0x04
0158 #define EMAC_INT_STA    0x08
0159 #define EMAC_INT_EN     0x0C
0160 #define EMAC_TX_CTL0    0x10
0161 #define EMAC_TX_CTL1    0x14
0162 #define EMAC_TX_FLOW_CTL        0x1C
0163 #define EMAC_TX_DESC_LIST 0x20
0164 #define EMAC_RX_CTL0    0x24
0165 #define EMAC_RX_CTL1    0x28
0166 #define EMAC_RX_DESC_LIST 0x34
0167 #define EMAC_RX_FRM_FLT 0x38
0168 #define EMAC_MDIO_CMD   0x48
0169 #define EMAC_MDIO_DATA  0x4C
0170 #define EMAC_MACADDR_HI(reg) (0x50 + (reg) * 8)
0171 #define EMAC_MACADDR_LO(reg) (0x54 + (reg) * 8)
0172 #define EMAC_TX_DMA_STA 0xB0
0173 #define EMAC_TX_CUR_DESC        0xB4
0174 #define EMAC_TX_CUR_BUF 0xB8
0175 #define EMAC_RX_DMA_STA 0xC0
0176 #define EMAC_RX_CUR_DESC        0xC4
0177 #define EMAC_RX_CUR_BUF 0xC8
0178 
0179 /* Use in EMAC_BASIC_CTL0 */
0180 #define EMAC_DUPLEX_FULL    BIT(0)
0181 #define EMAC_LOOPBACK       BIT(1)
0182 #define EMAC_SPEED_1000 0
0183 #define EMAC_SPEED_100 (0x03 << 2)
0184 #define EMAC_SPEED_10 (0x02 << 2)
0185 
0186 /* Use in EMAC_BASIC_CTL1 */
0187 #define EMAC_BURSTLEN_SHIFT     24
0188 
0189 /* Used in EMAC_RX_FRM_FLT */
0190 #define EMAC_FRM_FLT_RXALL              BIT(0)
0191 #define EMAC_FRM_FLT_CTL                BIT(13)
0192 #define EMAC_FRM_FLT_MULTICAST          BIT(16)
0193 
0194 /* Used in RX_CTL1*/
0195 #define EMAC_RX_MD              BIT(1)
0196 #define EMAC_RX_TH_MASK     GENMASK(5, 4)
0197 #define EMAC_RX_TH_32       0
0198 #define EMAC_RX_TH_64       (0x1 << 4)
0199 #define EMAC_RX_TH_96       (0x2 << 4)
0200 #define EMAC_RX_TH_128      (0x3 << 4)
0201 #define EMAC_RX_DMA_EN  BIT(30)
0202 #define EMAC_RX_DMA_START       BIT(31)
0203 
0204 /* Used in TX_CTL1*/
0205 #define EMAC_TX_MD              BIT(1)
0206 #define EMAC_TX_NEXT_FRM        BIT(2)
0207 #define EMAC_TX_TH_MASK     GENMASK(10, 8)
0208 #define EMAC_TX_TH_64       0
0209 #define EMAC_TX_TH_128      (0x1 << 8)
0210 #define EMAC_TX_TH_192      (0x2 << 8)
0211 #define EMAC_TX_TH_256      (0x3 << 8)
0212 #define EMAC_TX_DMA_EN  BIT(30)
0213 #define EMAC_TX_DMA_START       BIT(31)
0214 
0215 /* Used in RX_CTL0 */
0216 #define EMAC_RX_RECEIVER_EN             BIT(31)
0217 #define EMAC_RX_DO_CRC BIT(27)
0218 #define EMAC_RX_FLOW_CTL_EN             BIT(16)
0219 
0220 /* Used in TX_CTL0 */
0221 #define EMAC_TX_TRANSMITTER_EN  BIT(31)
0222 
0223 /* Used in EMAC_TX_FLOW_CTL */
0224 #define EMAC_TX_FLOW_CTL_EN             BIT(0)
0225 
0226 /* Used in EMAC_INT_STA */
0227 #define EMAC_TX_INT             BIT(0)
0228 #define EMAC_TX_DMA_STOP_INT    BIT(1)
0229 #define EMAC_TX_BUF_UA_INT      BIT(2)
0230 #define EMAC_TX_TIMEOUT_INT     BIT(3)
0231 #define EMAC_TX_UNDERFLOW_INT   BIT(4)
0232 #define EMAC_TX_EARLY_INT       BIT(5)
0233 #define EMAC_RX_INT             BIT(8)
0234 #define EMAC_RX_BUF_UA_INT      BIT(9)
0235 #define EMAC_RX_DMA_STOP_INT    BIT(10)
0236 #define EMAC_RX_TIMEOUT_INT     BIT(11)
0237 #define EMAC_RX_OVERFLOW_INT    BIT(12)
0238 #define EMAC_RX_EARLY_INT       BIT(13)
0239 #define EMAC_RGMII_STA_INT      BIT(16)
0240 
0241 #define EMAC_INT_MSK_COMMON EMAC_RGMII_STA_INT
0242 #define EMAC_INT_MSK_TX     (EMAC_TX_INT | \
0243                  EMAC_TX_DMA_STOP_INT | \
0244                  EMAC_TX_BUF_UA_INT | \
0245                  EMAC_TX_TIMEOUT_INT | \
0246                  EMAC_TX_UNDERFLOW_INT | \
0247                  EMAC_TX_EARLY_INT |\
0248                  EMAC_INT_MSK_COMMON)
0249 #define EMAC_INT_MSK_RX     (EMAC_RX_INT | \
0250                  EMAC_RX_BUF_UA_INT | \
0251                  EMAC_RX_DMA_STOP_INT | \
0252                  EMAC_RX_TIMEOUT_INT | \
0253                  EMAC_RX_OVERFLOW_INT | \
0254                  EMAC_RX_EARLY_INT | \
0255                  EMAC_INT_MSK_COMMON)
0256 
0257 #define MAC_ADDR_TYPE_DST BIT(31)
0258 
0259 /* H3 specific bits for EPHY */
0260 #define H3_EPHY_ADDR_SHIFT  20
0261 #define H3_EPHY_CLK_SEL     BIT(18) /* 1: 24MHz, 0: 25MHz */
0262 #define H3_EPHY_LED_POL     BIT(17) /* 1: active low, 0: active high */
0263 #define H3_EPHY_SHUTDOWN    BIT(16) /* 1: shutdown, 0: power up */
0264 #define H3_EPHY_SELECT      BIT(15) /* 1: internal PHY, 0: external PHY */
0265 #define H3_EPHY_MUX_MASK    (H3_EPHY_SHUTDOWN | H3_EPHY_SELECT)
0266 #define DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID    1
0267 #define DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID    2
0268 
0269 /* H3/A64 specific bits */
0270 #define SYSCON_RMII_EN      BIT(13) /* 1: enable RMII (overrides EPIT) */
0271 
0272 /* Generic system control EMAC_CLK bits */
0273 #define SYSCON_ETXDC_SHIFT      10
0274 #define SYSCON_ERXDC_SHIFT      5
0275 /* EMAC PHY Interface Type */
0276 #define SYSCON_EPIT         BIT(2) /* 1: RGMII, 0: MII */
0277 #define SYSCON_ETCS_MASK        GENMASK(1, 0)
0278 #define SYSCON_ETCS_MII     0x0
0279 #define SYSCON_ETCS_EXT_GMII    0x1
0280 #define SYSCON_ETCS_INT_GMII    0x2
0281 
0282 /* sun8i_dwmac_dma_reset() - reset the EMAC
0283  * Called from stmmac via stmmac_dma_ops->reset
0284  */
0285 static int sun8i_dwmac_dma_reset(void __iomem *ioaddr)
0286 {
0287     writel(0, ioaddr + EMAC_RX_CTL1);
0288     writel(0, ioaddr + EMAC_TX_CTL1);
0289     writel(0, ioaddr + EMAC_RX_FRM_FLT);
0290     writel(0, ioaddr + EMAC_RX_DESC_LIST);
0291     writel(0, ioaddr + EMAC_TX_DESC_LIST);
0292     writel(0, ioaddr + EMAC_INT_EN);
0293     writel(0x1FFFFFF, ioaddr + EMAC_INT_STA);
0294     return 0;
0295 }
0296 
0297 /* sun8i_dwmac_dma_init() - initialize the EMAC
0298  * Called from stmmac via stmmac_dma_ops->init
0299  */
0300 static void sun8i_dwmac_dma_init(void __iomem *ioaddr,
0301                  struct stmmac_dma_cfg *dma_cfg, int atds)
0302 {
0303     writel(EMAC_RX_INT | EMAC_TX_INT, ioaddr + EMAC_INT_EN);
0304     writel(0x1FFFFFF, ioaddr + EMAC_INT_STA);
0305 }
0306 
0307 static void sun8i_dwmac_dma_init_rx(void __iomem *ioaddr,
0308                     struct stmmac_dma_cfg *dma_cfg,
0309                     dma_addr_t dma_rx_phy, u32 chan)
0310 {
0311     /* Write RX descriptors address */
0312     writel(lower_32_bits(dma_rx_phy), ioaddr + EMAC_RX_DESC_LIST);
0313 }
0314 
0315 static void sun8i_dwmac_dma_init_tx(void __iomem *ioaddr,
0316                     struct stmmac_dma_cfg *dma_cfg,
0317                     dma_addr_t dma_tx_phy, u32 chan)
0318 {
0319     /* Write TX descriptors address */
0320     writel(lower_32_bits(dma_tx_phy), ioaddr + EMAC_TX_DESC_LIST);
0321 }
0322 
0323 /* sun8i_dwmac_dump_regs() - Dump EMAC address space
0324  * Called from stmmac_dma_ops->dump_regs
0325  * Used for ethtool
0326  */
0327 static void sun8i_dwmac_dump_regs(void __iomem *ioaddr, u32 *reg_space)
0328 {
0329     int i;
0330 
0331     for (i = 0; i < 0xC8; i += 4) {
0332         if (i == 0x32 || i == 0x3C)
0333             continue;
0334         reg_space[i / 4] = readl(ioaddr + i);
0335     }
0336 }
0337 
0338 /* sun8i_dwmac_dump_mac_regs() - Dump EMAC address space
0339  * Called from stmmac_ops->dump_regs
0340  * Used for ethtool
0341  */
0342 static void sun8i_dwmac_dump_mac_regs(struct mac_device_info *hw,
0343                       u32 *reg_space)
0344 {
0345     int i;
0346     void __iomem *ioaddr = hw->pcsr;
0347 
0348     for (i = 0; i < 0xC8; i += 4) {
0349         if (i == 0x32 || i == 0x3C)
0350             continue;
0351         reg_space[i / 4] = readl(ioaddr + i);
0352     }
0353 }
0354 
0355 static void sun8i_dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan,
0356                        bool rx, bool tx)
0357 {
0358     u32 value = readl(ioaddr + EMAC_INT_EN);
0359 
0360     if (rx)
0361         value |= EMAC_RX_INT;
0362     if (tx)
0363         value |= EMAC_TX_INT;
0364 
0365     writel(value, ioaddr + EMAC_INT_EN);
0366 }
0367 
0368 static void sun8i_dwmac_disable_dma_irq(void __iomem *ioaddr, u32 chan,
0369                     bool rx, bool tx)
0370 {
0371     u32 value = readl(ioaddr + EMAC_INT_EN);
0372 
0373     if (rx)
0374         value &= ~EMAC_RX_INT;
0375     if (tx)
0376         value &= ~EMAC_TX_INT;
0377 
0378     writel(value, ioaddr + EMAC_INT_EN);
0379 }
0380 
0381 static void sun8i_dwmac_dma_start_tx(void __iomem *ioaddr, u32 chan)
0382 {
0383     u32 v;
0384 
0385     v = readl(ioaddr + EMAC_TX_CTL1);
0386     v |= EMAC_TX_DMA_START;
0387     v |= EMAC_TX_DMA_EN;
0388     writel(v, ioaddr + EMAC_TX_CTL1);
0389 }
0390 
0391 static void sun8i_dwmac_enable_dma_transmission(void __iomem *ioaddr)
0392 {
0393     u32 v;
0394 
0395     v = readl(ioaddr + EMAC_TX_CTL1);
0396     v |= EMAC_TX_DMA_START;
0397     v |= EMAC_TX_DMA_EN;
0398     writel(v, ioaddr + EMAC_TX_CTL1);
0399 }
0400 
0401 static void sun8i_dwmac_dma_stop_tx(void __iomem *ioaddr, u32 chan)
0402 {
0403     u32 v;
0404 
0405     v = readl(ioaddr + EMAC_TX_CTL1);
0406     v &= ~EMAC_TX_DMA_EN;
0407     writel(v, ioaddr + EMAC_TX_CTL1);
0408 }
0409 
0410 static void sun8i_dwmac_dma_start_rx(void __iomem *ioaddr, u32 chan)
0411 {
0412     u32 v;
0413 
0414     v = readl(ioaddr + EMAC_RX_CTL1);
0415     v |= EMAC_RX_DMA_START;
0416     v |= EMAC_RX_DMA_EN;
0417     writel(v, ioaddr + EMAC_RX_CTL1);
0418 }
0419 
0420 static void sun8i_dwmac_dma_stop_rx(void __iomem *ioaddr, u32 chan)
0421 {
0422     u32 v;
0423 
0424     v = readl(ioaddr + EMAC_RX_CTL1);
0425     v &= ~EMAC_RX_DMA_EN;
0426     writel(v, ioaddr + EMAC_RX_CTL1);
0427 }
0428 
0429 static int sun8i_dwmac_dma_interrupt(void __iomem *ioaddr,
0430                      struct stmmac_extra_stats *x, u32 chan,
0431                      u32 dir)
0432 {
0433     u32 v;
0434     int ret = 0;
0435 
0436     v = readl(ioaddr + EMAC_INT_STA);
0437 
0438     if (dir == DMA_DIR_RX)
0439         v &= EMAC_INT_MSK_RX;
0440     else if (dir == DMA_DIR_TX)
0441         v &= EMAC_INT_MSK_TX;
0442 
0443     if (v & EMAC_TX_INT) {
0444         ret |= handle_tx;
0445         x->tx_normal_irq_n++;
0446     }
0447 
0448     if (v & EMAC_TX_DMA_STOP_INT)
0449         x->tx_process_stopped_irq++;
0450 
0451     if (v & EMAC_TX_BUF_UA_INT)
0452         x->tx_process_stopped_irq++;
0453 
0454     if (v & EMAC_TX_TIMEOUT_INT)
0455         ret |= tx_hard_error;
0456 
0457     if (v & EMAC_TX_UNDERFLOW_INT) {
0458         ret |= tx_hard_error;
0459         x->tx_undeflow_irq++;
0460     }
0461 
0462     if (v & EMAC_TX_EARLY_INT)
0463         x->tx_early_irq++;
0464 
0465     if (v & EMAC_RX_INT) {
0466         ret |= handle_rx;
0467         x->rx_normal_irq_n++;
0468     }
0469 
0470     if (v & EMAC_RX_BUF_UA_INT)
0471         x->rx_buf_unav_irq++;
0472 
0473     if (v & EMAC_RX_DMA_STOP_INT)
0474         x->rx_process_stopped_irq++;
0475 
0476     if (v & EMAC_RX_TIMEOUT_INT)
0477         ret |= tx_hard_error;
0478 
0479     if (v & EMAC_RX_OVERFLOW_INT) {
0480         ret |= tx_hard_error;
0481         x->rx_overflow_irq++;
0482     }
0483 
0484     if (v & EMAC_RX_EARLY_INT)
0485         x->rx_early_irq++;
0486 
0487     if (v & EMAC_RGMII_STA_INT)
0488         x->irq_rgmii_n++;
0489 
0490     writel(v, ioaddr + EMAC_INT_STA);
0491 
0492     return ret;
0493 }
0494 
0495 static void sun8i_dwmac_dma_operation_mode_rx(void __iomem *ioaddr, int mode,
0496                           u32 channel, int fifosz, u8 qmode)
0497 {
0498     u32 v;
0499 
0500     v = readl(ioaddr + EMAC_RX_CTL1);
0501     if (mode == SF_DMA_MODE) {
0502         v |= EMAC_RX_MD;
0503     } else {
0504         v &= ~EMAC_RX_MD;
0505         v &= ~EMAC_RX_TH_MASK;
0506         if (mode < 32)
0507             v |= EMAC_RX_TH_32;
0508         else if (mode < 64)
0509             v |= EMAC_RX_TH_64;
0510         else if (mode < 96)
0511             v |= EMAC_RX_TH_96;
0512         else if (mode < 128)
0513             v |= EMAC_RX_TH_128;
0514     }
0515     writel(v, ioaddr + EMAC_RX_CTL1);
0516 }
0517 
0518 static void sun8i_dwmac_dma_operation_mode_tx(void __iomem *ioaddr, int mode,
0519                           u32 channel, int fifosz, u8 qmode)
0520 {
0521     u32 v;
0522 
0523     v = readl(ioaddr + EMAC_TX_CTL1);
0524     if (mode == SF_DMA_MODE) {
0525         v |= EMAC_TX_MD;
0526         /* Undocumented bit (called TX_NEXT_FRM in BSP), the original
0527          * comment is
0528          * "Operating on second frame increase the performance
0529          * especially when transmit store-and-forward is used."
0530          */
0531         v |= EMAC_TX_NEXT_FRM;
0532     } else {
0533         v &= ~EMAC_TX_MD;
0534         v &= ~EMAC_TX_TH_MASK;
0535         if (mode < 64)
0536             v |= EMAC_TX_TH_64;
0537         else if (mode < 128)
0538             v |= EMAC_TX_TH_128;
0539         else if (mode < 192)
0540             v |= EMAC_TX_TH_192;
0541         else if (mode < 256)
0542             v |= EMAC_TX_TH_256;
0543     }
0544     writel(v, ioaddr + EMAC_TX_CTL1);
0545 }
0546 
0547 static const struct stmmac_dma_ops sun8i_dwmac_dma_ops = {
0548     .reset = sun8i_dwmac_dma_reset,
0549     .init = sun8i_dwmac_dma_init,
0550     .init_rx_chan = sun8i_dwmac_dma_init_rx,
0551     .init_tx_chan = sun8i_dwmac_dma_init_tx,
0552     .dump_regs = sun8i_dwmac_dump_regs,
0553     .dma_rx_mode = sun8i_dwmac_dma_operation_mode_rx,
0554     .dma_tx_mode = sun8i_dwmac_dma_operation_mode_tx,
0555     .enable_dma_transmission = sun8i_dwmac_enable_dma_transmission,
0556     .enable_dma_irq = sun8i_dwmac_enable_dma_irq,
0557     .disable_dma_irq = sun8i_dwmac_disable_dma_irq,
0558     .start_tx = sun8i_dwmac_dma_start_tx,
0559     .stop_tx = sun8i_dwmac_dma_stop_tx,
0560     .start_rx = sun8i_dwmac_dma_start_rx,
0561     .stop_rx = sun8i_dwmac_dma_stop_rx,
0562     .dma_interrupt = sun8i_dwmac_dma_interrupt,
0563 };
0564 
0565 static int sun8i_dwmac_power_internal_phy(struct stmmac_priv *priv);
0566 
0567 static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
0568 {
0569     struct net_device *ndev = platform_get_drvdata(pdev);
0570     struct sunxi_priv_data *gmac = priv;
0571     int ret;
0572 
0573     if (gmac->regulator) {
0574         ret = regulator_enable(gmac->regulator);
0575         if (ret) {
0576             dev_err(&pdev->dev, "Fail to enable regulator\n");
0577             return ret;
0578         }
0579     }
0580 
0581     if (gmac->use_internal_phy) {
0582         ret = sun8i_dwmac_power_internal_phy(netdev_priv(ndev));
0583         if (ret)
0584             goto err_disable_regulator;
0585     }
0586 
0587     return 0;
0588 
0589 err_disable_regulator:
0590     if (gmac->regulator)
0591         regulator_disable(gmac->regulator);
0592 
0593     return ret;
0594 }
0595 
0596 static void sun8i_dwmac_core_init(struct mac_device_info *hw,
0597                   struct net_device *dev)
0598 {
0599     void __iomem *ioaddr = hw->pcsr;
0600     u32 v;
0601 
0602     v = (8 << EMAC_BURSTLEN_SHIFT); /* burst len */
0603     writel(v, ioaddr + EMAC_BASIC_CTL1);
0604 }
0605 
0606 static void sun8i_dwmac_set_mac(void __iomem *ioaddr, bool enable)
0607 {
0608     u32 t, r;
0609 
0610     t = readl(ioaddr + EMAC_TX_CTL0);
0611     r = readl(ioaddr + EMAC_RX_CTL0);
0612     if (enable) {
0613         t |= EMAC_TX_TRANSMITTER_EN;
0614         r |= EMAC_RX_RECEIVER_EN;
0615     } else {
0616         t &= ~EMAC_TX_TRANSMITTER_EN;
0617         r &= ~EMAC_RX_RECEIVER_EN;
0618     }
0619     writel(t, ioaddr + EMAC_TX_CTL0);
0620     writel(r, ioaddr + EMAC_RX_CTL0);
0621 }
0622 
0623 /* Set MAC address at slot reg_n
0624  * All slot > 0 need to be enabled with MAC_ADDR_TYPE_DST
0625  * If addr is NULL, clear the slot
0626  */
0627 static void sun8i_dwmac_set_umac_addr(struct mac_device_info *hw,
0628                       const unsigned char *addr,
0629                       unsigned int reg_n)
0630 {
0631     void __iomem *ioaddr = hw->pcsr;
0632     u32 v;
0633 
0634     if (!addr) {
0635         writel(0, ioaddr + EMAC_MACADDR_HI(reg_n));
0636         return;
0637     }
0638 
0639     stmmac_set_mac_addr(ioaddr, addr, EMAC_MACADDR_HI(reg_n),
0640                 EMAC_MACADDR_LO(reg_n));
0641     if (reg_n > 0) {
0642         v = readl(ioaddr + EMAC_MACADDR_HI(reg_n));
0643         v |= MAC_ADDR_TYPE_DST;
0644         writel(v, ioaddr + EMAC_MACADDR_HI(reg_n));
0645     }
0646 }
0647 
0648 static void sun8i_dwmac_get_umac_addr(struct mac_device_info *hw,
0649                       unsigned char *addr,
0650                       unsigned int reg_n)
0651 {
0652     void __iomem *ioaddr = hw->pcsr;
0653 
0654     stmmac_get_mac_addr(ioaddr, addr, EMAC_MACADDR_HI(reg_n),
0655                 EMAC_MACADDR_LO(reg_n));
0656 }
0657 
0658 /* caution this function must return non 0 to work */
0659 static int sun8i_dwmac_rx_ipc_enable(struct mac_device_info *hw)
0660 {
0661     void __iomem *ioaddr = hw->pcsr;
0662     u32 v;
0663 
0664     v = readl(ioaddr + EMAC_RX_CTL0);
0665     v |= EMAC_RX_DO_CRC;
0666     writel(v, ioaddr + EMAC_RX_CTL0);
0667 
0668     return 1;
0669 }
0670 
0671 static void sun8i_dwmac_set_filter(struct mac_device_info *hw,
0672                    struct net_device *dev)
0673 {
0674     void __iomem *ioaddr = hw->pcsr;
0675     u32 v;
0676     int i = 1;
0677     struct netdev_hw_addr *ha;
0678     int macaddrs = netdev_uc_count(dev) + netdev_mc_count(dev) + 1;
0679 
0680     v = EMAC_FRM_FLT_CTL;
0681 
0682     if (dev->flags & IFF_PROMISC) {
0683         v = EMAC_FRM_FLT_RXALL;
0684     } else if (dev->flags & IFF_ALLMULTI) {
0685         v |= EMAC_FRM_FLT_MULTICAST;
0686     } else if (macaddrs <= hw->unicast_filter_entries) {
0687         if (!netdev_mc_empty(dev)) {
0688             netdev_for_each_mc_addr(ha, dev) {
0689                 sun8i_dwmac_set_umac_addr(hw, ha->addr, i);
0690                 i++;
0691             }
0692         }
0693         if (!netdev_uc_empty(dev)) {
0694             netdev_for_each_uc_addr(ha, dev) {
0695                 sun8i_dwmac_set_umac_addr(hw, ha->addr, i);
0696                 i++;
0697             }
0698         }
0699     } else {
0700         if (!(readl(ioaddr + EMAC_RX_FRM_FLT) & EMAC_FRM_FLT_RXALL))
0701             netdev_info(dev, "Too many address, switching to promiscuous\n");
0702         v = EMAC_FRM_FLT_RXALL;
0703     }
0704 
0705     /* Disable unused address filter slots */
0706     while (i < hw->unicast_filter_entries)
0707         sun8i_dwmac_set_umac_addr(hw, NULL, i++);
0708 
0709     writel(v, ioaddr + EMAC_RX_FRM_FLT);
0710 }
0711 
0712 static void sun8i_dwmac_flow_ctrl(struct mac_device_info *hw,
0713                   unsigned int duplex, unsigned int fc,
0714                   unsigned int pause_time, u32 tx_cnt)
0715 {
0716     void __iomem *ioaddr = hw->pcsr;
0717     u32 v;
0718 
0719     v = readl(ioaddr + EMAC_RX_CTL0);
0720     if (fc == FLOW_AUTO)
0721         v |= EMAC_RX_FLOW_CTL_EN;
0722     else
0723         v &= ~EMAC_RX_FLOW_CTL_EN;
0724     writel(v, ioaddr + EMAC_RX_CTL0);
0725 
0726     v = readl(ioaddr + EMAC_TX_FLOW_CTL);
0727     if (fc == FLOW_AUTO)
0728         v |= EMAC_TX_FLOW_CTL_EN;
0729     else
0730         v &= ~EMAC_TX_FLOW_CTL_EN;
0731     writel(v, ioaddr + EMAC_TX_FLOW_CTL);
0732 }
0733 
0734 static int sun8i_dwmac_reset(struct stmmac_priv *priv)
0735 {
0736     u32 v;
0737     int err;
0738 
0739     v = readl(priv->ioaddr + EMAC_BASIC_CTL1);
0740     writel(v | 0x01, priv->ioaddr + EMAC_BASIC_CTL1);
0741 
0742     /* The timeout was previoulsy set to 10ms, but some board (OrangePI0)
0743      * need more if no cable plugged. 100ms seems OK
0744      */
0745     err = readl_poll_timeout(priv->ioaddr + EMAC_BASIC_CTL1, v,
0746                  !(v & 0x01), 100, 100000);
0747 
0748     if (err) {
0749         dev_err(priv->device, "EMAC reset timeout\n");
0750         return err;
0751     }
0752     return 0;
0753 }
0754 
0755 /* Search in mdio-mux node for internal PHY node and get its clk/reset */
0756 static int get_ephy_nodes(struct stmmac_priv *priv)
0757 {
0758     struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
0759     struct device_node *mdio_mux, *iphynode;
0760     struct device_node *mdio_internal;
0761     int ret;
0762 
0763     mdio_mux = of_get_child_by_name(priv->device->of_node, "mdio-mux");
0764     if (!mdio_mux) {
0765         dev_err(priv->device, "Cannot get mdio-mux node\n");
0766         return -ENODEV;
0767     }
0768 
0769     mdio_internal = of_get_compatible_child(mdio_mux,
0770                         "allwinner,sun8i-h3-mdio-internal");
0771     of_node_put(mdio_mux);
0772     if (!mdio_internal) {
0773         dev_err(priv->device, "Cannot get internal_mdio node\n");
0774         return -ENODEV;
0775     }
0776 
0777     /* Seek for internal PHY */
0778     for_each_child_of_node(mdio_internal, iphynode) {
0779         gmac->ephy_clk = of_clk_get(iphynode, 0);
0780         if (IS_ERR(gmac->ephy_clk))
0781             continue;
0782         gmac->rst_ephy = of_reset_control_get_exclusive(iphynode, NULL);
0783         if (IS_ERR(gmac->rst_ephy)) {
0784             ret = PTR_ERR(gmac->rst_ephy);
0785             if (ret == -EPROBE_DEFER) {
0786                 of_node_put(iphynode);
0787                 of_node_put(mdio_internal);
0788                 return ret;
0789             }
0790             continue;
0791         }
0792         dev_info(priv->device, "Found internal PHY node\n");
0793         of_node_put(iphynode);
0794         of_node_put(mdio_internal);
0795         return 0;
0796     }
0797 
0798     of_node_put(mdio_internal);
0799     return -ENODEV;
0800 }
0801 
0802 static int sun8i_dwmac_power_internal_phy(struct stmmac_priv *priv)
0803 {
0804     struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
0805     int ret;
0806 
0807     if (gmac->internal_phy_powered) {
0808         dev_warn(priv->device, "Internal PHY already powered\n");
0809         return 0;
0810     }
0811 
0812     dev_info(priv->device, "Powering internal PHY\n");
0813     ret = clk_prepare_enable(gmac->ephy_clk);
0814     if (ret) {
0815         dev_err(priv->device, "Cannot enable internal PHY\n");
0816         return ret;
0817     }
0818 
0819     /* Make sure the EPHY is properly reseted, as U-Boot may leave
0820      * it at deasserted state, and thus it may fail to reset EMAC.
0821      *
0822      * This assumes the driver has exclusive access to the EPHY reset.
0823      */
0824     ret = reset_control_reset(gmac->rst_ephy);
0825     if (ret) {
0826         dev_err(priv->device, "Cannot reset internal PHY\n");
0827         clk_disable_unprepare(gmac->ephy_clk);
0828         return ret;
0829     }
0830 
0831     gmac->internal_phy_powered = true;
0832 
0833     return 0;
0834 }
0835 
0836 static void sun8i_dwmac_unpower_internal_phy(struct sunxi_priv_data *gmac)
0837 {
0838     if (!gmac->internal_phy_powered)
0839         return;
0840 
0841     clk_disable_unprepare(gmac->ephy_clk);
0842     reset_control_assert(gmac->rst_ephy);
0843     gmac->internal_phy_powered = false;
0844 }
0845 
0846 /* MDIO multiplexing switch function
0847  * This function is called by the mdio-mux layer when it thinks the mdio bus
0848  * multiplexer needs to switch.
0849  * 'current_child' is the current value of the mux register
0850  * 'desired_child' is the value of the 'reg' property of the target child MDIO
0851  * node.
0852  * The first time this function is called, current_child == -1.
0853  * If current_child == desired_child, then the mux is already set to the
0854  * correct bus.
0855  */
0856 static int mdio_mux_syscon_switch_fn(int current_child, int desired_child,
0857                      void *data)
0858 {
0859     struct stmmac_priv *priv = data;
0860     struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
0861     u32 reg, val;
0862     int ret = 0;
0863 
0864     if (current_child ^ desired_child) {
0865         regmap_field_read(gmac->regmap_field, &reg);
0866         switch (desired_child) {
0867         case DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID:
0868             dev_info(priv->device, "Switch mux to internal PHY");
0869             val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SELECT;
0870             gmac->use_internal_phy = true;
0871             break;
0872         case DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID:
0873             dev_info(priv->device, "Switch mux to external PHY");
0874             val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SHUTDOWN;
0875             gmac->use_internal_phy = false;
0876             break;
0877         default:
0878             dev_err(priv->device, "Invalid child ID %x\n",
0879                 desired_child);
0880             return -EINVAL;
0881         }
0882         regmap_field_write(gmac->regmap_field, val);
0883         if (gmac->use_internal_phy) {
0884             ret = sun8i_dwmac_power_internal_phy(priv);
0885             if (ret)
0886                 return ret;
0887         } else {
0888             sun8i_dwmac_unpower_internal_phy(gmac);
0889         }
0890         /* After changing syscon value, the MAC need reset or it will
0891          * use the last value (and so the last PHY set).
0892          */
0893         ret = sun8i_dwmac_reset(priv);
0894     }
0895     return ret;
0896 }
0897 
0898 static int sun8i_dwmac_register_mdio_mux(struct stmmac_priv *priv)
0899 {
0900     int ret;
0901     struct device_node *mdio_mux;
0902     struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
0903 
0904     mdio_mux = of_get_child_by_name(priv->device->of_node, "mdio-mux");
0905     if (!mdio_mux)
0906         return -ENODEV;
0907 
0908     ret = mdio_mux_init(priv->device, mdio_mux, mdio_mux_syscon_switch_fn,
0909                 &gmac->mux_handle, priv, priv->mii);
0910     of_node_put(mdio_mux);
0911     return ret;
0912 }
0913 
0914 static int sun8i_dwmac_set_syscon(struct device *dev,
0915                   struct plat_stmmacenet_data *plat)
0916 {
0917     struct sunxi_priv_data *gmac = plat->bsp_priv;
0918     struct device_node *node = dev->of_node;
0919     int ret;
0920     u32 reg, val;
0921 
0922     ret = regmap_field_read(gmac->regmap_field, &val);
0923     if (ret) {
0924         dev_err(dev, "Fail to read from regmap field.\n");
0925         return ret;
0926     }
0927 
0928     reg = gmac->variant->default_syscon_value;
0929     if (reg != val)
0930         dev_warn(dev,
0931              "Current syscon value is not the default %x (expect %x)\n",
0932              val, reg);
0933 
0934     if (gmac->variant->soc_has_internal_phy) {
0935         if (of_property_read_bool(node, "allwinner,leds-active-low"))
0936             reg |= H3_EPHY_LED_POL;
0937         else
0938             reg &= ~H3_EPHY_LED_POL;
0939 
0940         /* Force EPHY xtal frequency to 24MHz. */
0941         reg |= H3_EPHY_CLK_SEL;
0942 
0943         ret = of_mdio_parse_addr(dev, plat->phy_node);
0944         if (ret < 0) {
0945             dev_err(dev, "Could not parse MDIO addr\n");
0946             return ret;
0947         }
0948         /* of_mdio_parse_addr returns a valid (0 ~ 31) PHY
0949          * address. No need to mask it again.
0950          */
0951         reg |= 1 << H3_EPHY_ADDR_SHIFT;
0952     } else {
0953         /* For SoCs without internal PHY the PHY selection bit should be
0954          * set to 0 (external PHY).
0955          */
0956         reg &= ~H3_EPHY_SELECT;
0957     }
0958 
0959     if (!of_property_read_u32(node, "allwinner,tx-delay-ps", &val)) {
0960         if (val % 100) {
0961             dev_err(dev, "tx-delay must be a multiple of 100\n");
0962             return -EINVAL;
0963         }
0964         val /= 100;
0965         dev_dbg(dev, "set tx-delay to %x\n", val);
0966         if (val <= gmac->variant->tx_delay_max) {
0967             reg &= ~(gmac->variant->tx_delay_max <<
0968                  SYSCON_ETXDC_SHIFT);
0969             reg |= (val << SYSCON_ETXDC_SHIFT);
0970         } else {
0971             dev_err(dev, "Invalid TX clock delay: %d\n",
0972                 val);
0973             return -EINVAL;
0974         }
0975     }
0976 
0977     if (!of_property_read_u32(node, "allwinner,rx-delay-ps", &val)) {
0978         if (val % 100) {
0979             dev_err(dev, "rx-delay must be a multiple of 100\n");
0980             return -EINVAL;
0981         }
0982         val /= 100;
0983         dev_dbg(dev, "set rx-delay to %x\n", val);
0984         if (val <= gmac->variant->rx_delay_max) {
0985             reg &= ~(gmac->variant->rx_delay_max <<
0986                  SYSCON_ERXDC_SHIFT);
0987             reg |= (val << SYSCON_ERXDC_SHIFT);
0988         } else {
0989             dev_err(dev, "Invalid RX clock delay: %d\n",
0990                 val);
0991             return -EINVAL;
0992         }
0993     }
0994 
0995     /* Clear interface mode bits */
0996     reg &= ~(SYSCON_ETCS_MASK | SYSCON_EPIT);
0997     if (gmac->variant->support_rmii)
0998         reg &= ~SYSCON_RMII_EN;
0999 
1000     switch (plat->interface) {
1001     case PHY_INTERFACE_MODE_MII:
1002         /* default */
1003         break;
1004     case PHY_INTERFACE_MODE_RGMII:
1005     case PHY_INTERFACE_MODE_RGMII_ID:
1006     case PHY_INTERFACE_MODE_RGMII_RXID:
1007     case PHY_INTERFACE_MODE_RGMII_TXID:
1008         reg |= SYSCON_EPIT | SYSCON_ETCS_INT_GMII;
1009         break;
1010     case PHY_INTERFACE_MODE_RMII:
1011         reg |= SYSCON_RMII_EN | SYSCON_ETCS_EXT_GMII;
1012         break;
1013     default:
1014         dev_err(dev, "Unsupported interface mode: %s",
1015             phy_modes(plat->interface));
1016         return -EINVAL;
1017     }
1018 
1019     regmap_field_write(gmac->regmap_field, reg);
1020 
1021     return 0;
1022 }
1023 
1024 static void sun8i_dwmac_unset_syscon(struct sunxi_priv_data *gmac)
1025 {
1026     u32 reg = gmac->variant->default_syscon_value;
1027 
1028     regmap_field_write(gmac->regmap_field, reg);
1029 }
1030 
1031 static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv)
1032 {
1033     struct sunxi_priv_data *gmac = priv;
1034 
1035     if (gmac->variant->soc_has_internal_phy)
1036         sun8i_dwmac_unpower_internal_phy(gmac);
1037 
1038     if (gmac->regulator)
1039         regulator_disable(gmac->regulator);
1040 }
1041 
1042 static void sun8i_dwmac_set_mac_loopback(void __iomem *ioaddr, bool enable)
1043 {
1044     u32 value = readl(ioaddr + EMAC_BASIC_CTL0);
1045 
1046     if (enable)
1047         value |= EMAC_LOOPBACK;
1048     else
1049         value &= ~EMAC_LOOPBACK;
1050 
1051     writel(value, ioaddr + EMAC_BASIC_CTL0);
1052 }
1053 
1054 static const struct stmmac_ops sun8i_dwmac_ops = {
1055     .core_init = sun8i_dwmac_core_init,
1056     .set_mac = sun8i_dwmac_set_mac,
1057     .dump_regs = sun8i_dwmac_dump_mac_regs,
1058     .rx_ipc = sun8i_dwmac_rx_ipc_enable,
1059     .set_filter = sun8i_dwmac_set_filter,
1060     .flow_ctrl = sun8i_dwmac_flow_ctrl,
1061     .set_umac_addr = sun8i_dwmac_set_umac_addr,
1062     .get_umac_addr = sun8i_dwmac_get_umac_addr,
1063     .set_mac_loopback = sun8i_dwmac_set_mac_loopback,
1064 };
1065 
1066 static struct mac_device_info *sun8i_dwmac_setup(void *ppriv)
1067 {
1068     struct mac_device_info *mac;
1069     struct stmmac_priv *priv = ppriv;
1070 
1071     mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL);
1072     if (!mac)
1073         return NULL;
1074 
1075     mac->pcsr = priv->ioaddr;
1076     mac->mac = &sun8i_dwmac_ops;
1077     mac->dma = &sun8i_dwmac_dma_ops;
1078 
1079     priv->dev->priv_flags |= IFF_UNICAST_FLT;
1080 
1081     /* The loopback bit seems to be re-set when link change
1082      * Simply mask it each time
1083      * Speed 10/100/1000 are set in BIT(2)/BIT(3)
1084      */
1085     mac->link.speed_mask = GENMASK(3, 2) | EMAC_LOOPBACK;
1086     mac->link.speed10 = EMAC_SPEED_10;
1087     mac->link.speed100 = EMAC_SPEED_100;
1088     mac->link.speed1000 = EMAC_SPEED_1000;
1089     mac->link.duplex = EMAC_DUPLEX_FULL;
1090     mac->mii.addr = EMAC_MDIO_CMD;
1091     mac->mii.data = EMAC_MDIO_DATA;
1092     mac->mii.reg_shift = 4;
1093     mac->mii.reg_mask = GENMASK(8, 4);
1094     mac->mii.addr_shift = 12;
1095     mac->mii.addr_mask = GENMASK(16, 12);
1096     mac->mii.clk_csr_shift = 20;
1097     mac->mii.clk_csr_mask = GENMASK(22, 20);
1098     mac->unicast_filter_entries = 8;
1099 
1100     /* Synopsys Id is not available */
1101     priv->synopsys_id = 0;
1102 
1103     return mac;
1104 }
1105 
1106 static struct regmap *sun8i_dwmac_get_syscon_from_dev(struct device_node *node)
1107 {
1108     struct device_node *syscon_node;
1109     struct platform_device *syscon_pdev;
1110     struct regmap *regmap = NULL;
1111 
1112     syscon_node = of_parse_phandle(node, "syscon", 0);
1113     if (!syscon_node)
1114         return ERR_PTR(-ENODEV);
1115 
1116     syscon_pdev = of_find_device_by_node(syscon_node);
1117     if (!syscon_pdev) {
1118         /* platform device might not be probed yet */
1119         regmap = ERR_PTR(-EPROBE_DEFER);
1120         goto out_put_node;
1121     }
1122 
1123     /* If no regmap is found then the other device driver is at fault */
1124     regmap = dev_get_regmap(&syscon_pdev->dev, NULL);
1125     if (!regmap)
1126         regmap = ERR_PTR(-EINVAL);
1127 
1128     platform_device_put(syscon_pdev);
1129 out_put_node:
1130     of_node_put(syscon_node);
1131     return regmap;
1132 }
1133 
1134 static int sun8i_dwmac_probe(struct platform_device *pdev)
1135 {
1136     struct plat_stmmacenet_data *plat_dat;
1137     struct stmmac_resources stmmac_res;
1138     struct sunxi_priv_data *gmac;
1139     struct device *dev = &pdev->dev;
1140     phy_interface_t interface;
1141     int ret;
1142     struct stmmac_priv *priv;
1143     struct net_device *ndev;
1144     struct regmap *regmap;
1145 
1146     ret = stmmac_get_platform_resources(pdev, &stmmac_res);
1147     if (ret)
1148         return ret;
1149 
1150     gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
1151     if (!gmac)
1152         return -ENOMEM;
1153 
1154     gmac->variant = of_device_get_match_data(&pdev->dev);
1155     if (!gmac->variant) {
1156         dev_err(&pdev->dev, "Missing dwmac-sun8i variant\n");
1157         return -EINVAL;
1158     }
1159 
1160     /* Optional regulator for PHY */
1161     gmac->regulator = devm_regulator_get_optional(dev, "phy");
1162     if (IS_ERR(gmac->regulator)) {
1163         if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER)
1164             return -EPROBE_DEFER;
1165         dev_info(dev, "No regulator found\n");
1166         gmac->regulator = NULL;
1167     }
1168 
1169     /* The "GMAC clock control" register might be located in the
1170      * CCU address range (on the R40), or the system control address
1171      * range (on most other sun8i and later SoCs).
1172      *
1173      * The former controls most if not all clocks in the SoC. The
1174      * latter has an SoC identification register, and on some SoCs,
1175      * controls to map device specific SRAM to either the intended
1176      * peripheral, or the CPU address space.
1177      *
1178      * In either case, there should be a coordinated and restricted
1179      * method of accessing the register needed here. This is done by
1180      * having the device export a custom regmap, instead of a generic
1181      * syscon, which grants all access to all registers.
1182      *
1183      * To support old device trees, we fall back to using the syscon
1184      * interface if possible.
1185      */
1186     regmap = sun8i_dwmac_get_syscon_from_dev(pdev->dev.of_node);
1187     if (IS_ERR(regmap))
1188         regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
1189                              "syscon");
1190     if (IS_ERR(regmap)) {
1191         ret = PTR_ERR(regmap);
1192         dev_err(&pdev->dev, "Unable to map syscon: %d\n", ret);
1193         return ret;
1194     }
1195 
1196     gmac->regmap_field = devm_regmap_field_alloc(dev, regmap,
1197                              *gmac->variant->syscon_field);
1198     if (IS_ERR(gmac->regmap_field)) {
1199         ret = PTR_ERR(gmac->regmap_field);
1200         dev_err(dev, "Unable to map syscon register: %d\n", ret);
1201         return ret;
1202     }
1203 
1204     ret = of_get_phy_mode(dev->of_node, &interface);
1205     if (ret)
1206         return -EINVAL;
1207 
1208     plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
1209     if (IS_ERR(plat_dat))
1210         return PTR_ERR(plat_dat);
1211 
1212     /* platform data specifying hardware features and callbacks.
1213      * hardware features were copied from Allwinner drivers.
1214      */
1215     plat_dat->interface = interface;
1216     plat_dat->rx_coe = STMMAC_RX_COE_TYPE2;
1217     plat_dat->tx_coe = 1;
1218     plat_dat->has_sun8i = true;
1219     plat_dat->bsp_priv = gmac;
1220     plat_dat->init = sun8i_dwmac_init;
1221     plat_dat->exit = sun8i_dwmac_exit;
1222     plat_dat->setup = sun8i_dwmac_setup;
1223     plat_dat->tx_fifo_size = 4096;
1224     plat_dat->rx_fifo_size = 16384;
1225 
1226     ret = sun8i_dwmac_set_syscon(&pdev->dev, plat_dat);
1227     if (ret)
1228         goto dwmac_deconfig;
1229 
1230     ret = sun8i_dwmac_init(pdev, plat_dat->bsp_priv);
1231     if (ret)
1232         goto dwmac_syscon;
1233 
1234     ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
1235     if (ret)
1236         goto dwmac_exit;
1237 
1238     ndev = dev_get_drvdata(&pdev->dev);
1239     priv = netdev_priv(ndev);
1240 
1241     /* the MAC is runtime suspended after stmmac_dvr_probe(), so we
1242      * need to ensure the MAC resume back before other operations such
1243      * as reset.
1244      */
1245     pm_runtime_get_sync(&pdev->dev);
1246 
1247     /* The mux must be registered after parent MDIO
1248      * so after stmmac_dvr_probe()
1249      */
1250     if (gmac->variant->soc_has_internal_phy) {
1251         ret = get_ephy_nodes(priv);
1252         if (ret)
1253             goto dwmac_remove;
1254         ret = sun8i_dwmac_register_mdio_mux(priv);
1255         if (ret) {
1256             dev_err(&pdev->dev, "Failed to register mux\n");
1257             goto dwmac_mux;
1258         }
1259     } else {
1260         ret = sun8i_dwmac_reset(priv);
1261         if (ret)
1262             goto dwmac_remove;
1263     }
1264 
1265     pm_runtime_put(&pdev->dev);
1266 
1267     return 0;
1268 
1269 dwmac_mux:
1270     reset_control_put(gmac->rst_ephy);
1271     clk_put(gmac->ephy_clk);
1272 dwmac_remove:
1273     pm_runtime_put_noidle(&pdev->dev);
1274     stmmac_dvr_remove(&pdev->dev);
1275 dwmac_exit:
1276     sun8i_dwmac_exit(pdev, gmac);
1277 dwmac_syscon:
1278     sun8i_dwmac_unset_syscon(gmac);
1279 dwmac_deconfig:
1280     stmmac_remove_config_dt(pdev, plat_dat);
1281 
1282     return ret;
1283 }
1284 
1285 static int sun8i_dwmac_remove(struct platform_device *pdev)
1286 {
1287     struct net_device *ndev = platform_get_drvdata(pdev);
1288     struct stmmac_priv *priv = netdev_priv(ndev);
1289     struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
1290 
1291     if (gmac->variant->soc_has_internal_phy) {
1292         mdio_mux_uninit(gmac->mux_handle);
1293         sun8i_dwmac_unpower_internal_phy(gmac);
1294         reset_control_put(gmac->rst_ephy);
1295         clk_put(gmac->ephy_clk);
1296     }
1297 
1298     stmmac_pltfr_remove(pdev);
1299     sun8i_dwmac_unset_syscon(gmac);
1300 
1301     return 0;
1302 }
1303 
1304 static void sun8i_dwmac_shutdown(struct platform_device *pdev)
1305 {
1306     struct net_device *ndev = platform_get_drvdata(pdev);
1307     struct stmmac_priv *priv = netdev_priv(ndev);
1308     struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
1309 
1310     sun8i_dwmac_exit(pdev, gmac);
1311 }
1312 
1313 static const struct of_device_id sun8i_dwmac_match[] = {
1314     { .compatible = "allwinner,sun8i-h3-emac",
1315         .data = &emac_variant_h3 },
1316     { .compatible = "allwinner,sun8i-v3s-emac",
1317         .data = &emac_variant_v3s },
1318     { .compatible = "allwinner,sun8i-a83t-emac",
1319         .data = &emac_variant_a83t },
1320     { .compatible = "allwinner,sun8i-r40-gmac",
1321         .data = &emac_variant_r40 },
1322     { .compatible = "allwinner,sun50i-a64-emac",
1323         .data = &emac_variant_a64 },
1324     { .compatible = "allwinner,sun50i-h6-emac",
1325         .data = &emac_variant_h6 },
1326     { }
1327 };
1328 MODULE_DEVICE_TABLE(of, sun8i_dwmac_match);
1329 
1330 static struct platform_driver sun8i_dwmac_driver = {
1331     .probe  = sun8i_dwmac_probe,
1332     .remove = sun8i_dwmac_remove,
1333     .shutdown = sun8i_dwmac_shutdown,
1334     .driver = {
1335         .name           = "dwmac-sun8i",
1336         .pm     = &stmmac_pltfr_pm_ops,
1337         .of_match_table = sun8i_dwmac_match,
1338     },
1339 };
1340 module_platform_driver(sun8i_dwmac_driver);
1341 
1342 MODULE_AUTHOR("Corentin Labbe <clabbe.montjoie@gmail.com>");
1343 MODULE_DESCRIPTION("Allwinner sun8i DWMAC specific glue layer");
1344 MODULE_LICENSE("GPL");