Lines Matching +full:no +full:- +full:1 +full:- +full:8 +full:- +full:v

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * dwmac-sun8i.c - Allwinner sun8i DWMAC specific glue layer
11 #include <linux/mdio-mux.h>
26 /* General notes on dwmac-sun8i:
27 * Locking: no locking is necessary in this file because all necessary locking
31 /* struct emac_variant - Describe dwmac-sun8i hardware variant
59 /* struct sunxi_priv_data - hold all sunxi private data
67 * @mux_handle: Internal pointer used by mdio-mux lib
145 * co-packaged AC200 chip instead.
169 #define EMAC_MACADDR_HI(reg) (0x50 + (reg) * 8)
170 #define EMAC_MACADDR_LO(reg) (0x54 + (reg) * 8)
180 #define EMAC_LOOPBACK BIT(1)
194 #define EMAC_RX_MD BIT(1)
204 #define EMAC_TX_MD BIT(1)
206 #define EMAC_TX_TH_MASK GENMASK(10, 8)
208 #define EMAC_TX_TH_128 (0x1 << 8)
209 #define EMAC_TX_TH_192 (0x2 << 8)
210 #define EMAC_TX_TH_256 (0x3 << 8)
227 #define EMAC_TX_DMA_STOP_INT BIT(1)
232 #define EMAC_RX_INT BIT(8)
244 #define H3_EPHY_CLK_SEL BIT(18) /* 1: 24MHz, 0: 25MHz */
245 #define H3_EPHY_LED_POL BIT(17) /* 1: active low, 0: active high */
246 #define H3_EPHY_SHUTDOWN BIT(16) /* 1: shutdown, 0: power up */
247 #define H3_EPHY_SELECT BIT(15) /* 1: internal PHY, 0: external PHY */
249 #define DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID 1
253 #define SYSCON_RMII_EN BIT(13) /* 1: enable RMII (overrides EPIT) */
259 #define SYSCON_EPIT BIT(2) /* 1: RGMII, 0: MII */
260 #define SYSCON_ETCS_MASK GENMASK(1, 0)
265 /* sun8i_dwmac_dma_reset() - reset the EMAC
266 * Called from stmmac via stmmac_dma_ops->reset
280 /* sun8i_dwmac_dma_init() - initialize the EMAC
281 * Called from stmmac via stmmac_dma_ops->init
306 /* sun8i_dwmac_dump_regs() - Dump EMAC address space
307 * Called from stmmac_dma_ops->dump_regs
321 /* sun8i_dwmac_dump_mac_regs() - Dump EMAC address space
322 * Called from stmmac_ops->dump_regs
329 void __iomem *ioaddr = hw->pcsr; in sun8i_dwmac_dump_mac_regs()
366 u32 v; in sun8i_dwmac_dma_start_tx() local
368 v = readl(ioaddr + EMAC_TX_CTL1); in sun8i_dwmac_dma_start_tx()
369 v |= EMAC_TX_DMA_START; in sun8i_dwmac_dma_start_tx()
370 v |= EMAC_TX_DMA_EN; in sun8i_dwmac_dma_start_tx()
371 writel(v, ioaddr + EMAC_TX_CTL1); in sun8i_dwmac_dma_start_tx()
376 u32 v; in sun8i_dwmac_enable_dma_transmission() local
378 v = readl(ioaddr + EMAC_TX_CTL1); in sun8i_dwmac_enable_dma_transmission()
379 v |= EMAC_TX_DMA_START; in sun8i_dwmac_enable_dma_transmission()
380 v |= EMAC_TX_DMA_EN; in sun8i_dwmac_enable_dma_transmission()
381 writel(v, ioaddr + EMAC_TX_CTL1); in sun8i_dwmac_enable_dma_transmission()
386 u32 v; in sun8i_dwmac_dma_stop_tx() local
388 v = readl(ioaddr + EMAC_TX_CTL1); in sun8i_dwmac_dma_stop_tx()
389 v &= ~EMAC_TX_DMA_EN; in sun8i_dwmac_dma_stop_tx()
390 writel(v, ioaddr + EMAC_TX_CTL1); in sun8i_dwmac_dma_stop_tx()
395 u32 v; in sun8i_dwmac_dma_start_rx() local
397 v = readl(ioaddr + EMAC_RX_CTL1); in sun8i_dwmac_dma_start_rx()
398 v |= EMAC_RX_DMA_START; in sun8i_dwmac_dma_start_rx()
399 v |= EMAC_RX_DMA_EN; in sun8i_dwmac_dma_start_rx()
400 writel(v, ioaddr + EMAC_RX_CTL1); in sun8i_dwmac_dma_start_rx()
405 u32 v; in sun8i_dwmac_dma_stop_rx() local
407 v = readl(ioaddr + EMAC_RX_CTL1); in sun8i_dwmac_dma_stop_rx()
408 v &= ~EMAC_RX_DMA_EN; in sun8i_dwmac_dma_stop_rx()
409 writel(v, ioaddr + EMAC_RX_CTL1); in sun8i_dwmac_dma_stop_rx()
415 u32 v; in sun8i_dwmac_dma_interrupt() local
418 v = readl(ioaddr + EMAC_INT_STA); in sun8i_dwmac_dma_interrupt()
420 if (v & EMAC_TX_INT) { in sun8i_dwmac_dma_interrupt()
422 x->tx_normal_irq_n++; in sun8i_dwmac_dma_interrupt()
425 if (v & EMAC_TX_DMA_STOP_INT) in sun8i_dwmac_dma_interrupt()
426 x->tx_process_stopped_irq++; in sun8i_dwmac_dma_interrupt()
428 if (v & EMAC_TX_BUF_UA_INT) in sun8i_dwmac_dma_interrupt()
429 x->tx_process_stopped_irq++; in sun8i_dwmac_dma_interrupt()
431 if (v & EMAC_TX_TIMEOUT_INT) in sun8i_dwmac_dma_interrupt()
434 if (v & EMAC_TX_UNDERFLOW_INT) { in sun8i_dwmac_dma_interrupt()
436 x->tx_undeflow_irq++; in sun8i_dwmac_dma_interrupt()
439 if (v & EMAC_TX_EARLY_INT) in sun8i_dwmac_dma_interrupt()
440 x->tx_early_irq++; in sun8i_dwmac_dma_interrupt()
442 if (v & EMAC_RX_INT) { in sun8i_dwmac_dma_interrupt()
444 x->rx_normal_irq_n++; in sun8i_dwmac_dma_interrupt()
447 if (v & EMAC_RX_BUF_UA_INT) in sun8i_dwmac_dma_interrupt()
448 x->rx_buf_unav_irq++; in sun8i_dwmac_dma_interrupt()
450 if (v & EMAC_RX_DMA_STOP_INT) in sun8i_dwmac_dma_interrupt()
451 x->rx_process_stopped_irq++; in sun8i_dwmac_dma_interrupt()
453 if (v & EMAC_RX_TIMEOUT_INT) in sun8i_dwmac_dma_interrupt()
456 if (v & EMAC_RX_OVERFLOW_INT) { in sun8i_dwmac_dma_interrupt()
458 x->rx_overflow_irq++; in sun8i_dwmac_dma_interrupt()
461 if (v & EMAC_RX_EARLY_INT) in sun8i_dwmac_dma_interrupt()
462 x->rx_early_irq++; in sun8i_dwmac_dma_interrupt()
464 if (v & EMAC_RGMII_STA_INT) in sun8i_dwmac_dma_interrupt()
465 x->irq_rgmii_n++; in sun8i_dwmac_dma_interrupt()
467 writel(v, ioaddr + EMAC_INT_STA); in sun8i_dwmac_dma_interrupt()
475 u32 v; in sun8i_dwmac_dma_operation_mode_rx() local
477 v = readl(ioaddr + EMAC_RX_CTL1); in sun8i_dwmac_dma_operation_mode_rx()
479 v |= EMAC_RX_MD; in sun8i_dwmac_dma_operation_mode_rx()
481 v &= ~EMAC_RX_MD; in sun8i_dwmac_dma_operation_mode_rx()
482 v &= ~EMAC_RX_TH_MASK; in sun8i_dwmac_dma_operation_mode_rx()
484 v |= EMAC_RX_TH_32; in sun8i_dwmac_dma_operation_mode_rx()
486 v |= EMAC_RX_TH_64; in sun8i_dwmac_dma_operation_mode_rx()
488 v |= EMAC_RX_TH_96; in sun8i_dwmac_dma_operation_mode_rx()
490 v |= EMAC_RX_TH_128; in sun8i_dwmac_dma_operation_mode_rx()
492 writel(v, ioaddr + EMAC_RX_CTL1); in sun8i_dwmac_dma_operation_mode_rx()
498 u32 v; in sun8i_dwmac_dma_operation_mode_tx() local
500 v = readl(ioaddr + EMAC_TX_CTL1); in sun8i_dwmac_dma_operation_mode_tx()
502 v |= EMAC_TX_MD; in sun8i_dwmac_dma_operation_mode_tx()
506 * especially when transmit store-and-forward is used." in sun8i_dwmac_dma_operation_mode_tx()
508 v |= EMAC_TX_NEXT_FRM; in sun8i_dwmac_dma_operation_mode_tx()
510 v &= ~EMAC_TX_MD; in sun8i_dwmac_dma_operation_mode_tx()
511 v &= ~EMAC_TX_TH_MASK; in sun8i_dwmac_dma_operation_mode_tx()
513 v |= EMAC_TX_TH_64; in sun8i_dwmac_dma_operation_mode_tx()
515 v |= EMAC_TX_TH_128; in sun8i_dwmac_dma_operation_mode_tx()
517 v |= EMAC_TX_TH_192; in sun8i_dwmac_dma_operation_mode_tx()
519 v |= EMAC_TX_TH_256; in sun8i_dwmac_dma_operation_mode_tx()
521 writel(v, ioaddr + EMAC_TX_CTL1); in sun8i_dwmac_dma_operation_mode_tx()
547 if (gmac->regulator) { in sun8i_dwmac_init()
548 ret = regulator_enable(gmac->regulator); in sun8i_dwmac_init()
550 dev_err(&pdev->dev, "Fail to enable regulator\n"); in sun8i_dwmac_init()
555 ret = clk_prepare_enable(gmac->tx_clk); in sun8i_dwmac_init()
557 if (gmac->regulator) in sun8i_dwmac_init()
558 regulator_disable(gmac->regulator); in sun8i_dwmac_init()
559 dev_err(&pdev->dev, "Could not enable AHB clock\n"); in sun8i_dwmac_init()
569 void __iomem *ioaddr = hw->pcsr; in sun8i_dwmac_core_init()
570 u32 v; in sun8i_dwmac_core_init() local
572 v = (8 << EMAC_BURSTLEN_SHIFT); /* burst len */ in sun8i_dwmac_core_init()
573 writel(v, ioaddr + EMAC_BASIC_CTL1); in sun8i_dwmac_core_init()
601 void __iomem *ioaddr = hw->pcsr; in sun8i_dwmac_set_umac_addr()
602 u32 v; in sun8i_dwmac_set_umac_addr() local
612 v = readl(ioaddr + EMAC_MACADDR_HI(reg_n)); in sun8i_dwmac_set_umac_addr()
613 v |= MAC_ADDR_TYPE_DST; in sun8i_dwmac_set_umac_addr()
614 writel(v, ioaddr + EMAC_MACADDR_HI(reg_n)); in sun8i_dwmac_set_umac_addr()
622 void __iomem *ioaddr = hw->pcsr; in sun8i_dwmac_get_umac_addr()
631 void __iomem *ioaddr = hw->pcsr; in sun8i_dwmac_rx_ipc_enable()
632 u32 v; in sun8i_dwmac_rx_ipc_enable() local
634 v = readl(ioaddr + EMAC_RX_CTL0); in sun8i_dwmac_rx_ipc_enable()
635 v |= EMAC_RX_DO_CRC; in sun8i_dwmac_rx_ipc_enable()
636 writel(v, ioaddr + EMAC_RX_CTL0); in sun8i_dwmac_rx_ipc_enable()
638 return 1; in sun8i_dwmac_rx_ipc_enable()
644 void __iomem *ioaddr = hw->pcsr; in sun8i_dwmac_set_filter()
645 u32 v; in sun8i_dwmac_set_filter() local
646 int i = 1; in sun8i_dwmac_set_filter()
648 int macaddrs = netdev_uc_count(dev) + netdev_mc_count(dev) + 1; in sun8i_dwmac_set_filter()
650 v = EMAC_FRM_FLT_CTL; in sun8i_dwmac_set_filter()
652 if (dev->flags & IFF_PROMISC) { in sun8i_dwmac_set_filter()
653 v = EMAC_FRM_FLT_RXALL; in sun8i_dwmac_set_filter()
654 } else if (dev->flags & IFF_ALLMULTI) { in sun8i_dwmac_set_filter()
655 v |= EMAC_FRM_FLT_MULTICAST; in sun8i_dwmac_set_filter()
656 } else if (macaddrs <= hw->unicast_filter_entries) { in sun8i_dwmac_set_filter()
659 sun8i_dwmac_set_umac_addr(hw, ha->addr, i); in sun8i_dwmac_set_filter()
665 sun8i_dwmac_set_umac_addr(hw, ha->addr, i); in sun8i_dwmac_set_filter()
672 v = EMAC_FRM_FLT_RXALL; in sun8i_dwmac_set_filter()
676 while (i < hw->unicast_filter_entries) in sun8i_dwmac_set_filter()
679 writel(v, ioaddr + EMAC_RX_FRM_FLT); in sun8i_dwmac_set_filter()
686 void __iomem *ioaddr = hw->pcsr; in sun8i_dwmac_flow_ctrl()
687 u32 v; in sun8i_dwmac_flow_ctrl() local
689 v = readl(ioaddr + EMAC_RX_CTL0); in sun8i_dwmac_flow_ctrl()
691 v |= EMAC_RX_FLOW_CTL_EN; in sun8i_dwmac_flow_ctrl()
693 v &= ~EMAC_RX_FLOW_CTL_EN; in sun8i_dwmac_flow_ctrl()
694 writel(v, ioaddr + EMAC_RX_CTL0); in sun8i_dwmac_flow_ctrl()
696 v = readl(ioaddr + EMAC_TX_FLOW_CTL); in sun8i_dwmac_flow_ctrl()
698 v |= EMAC_TX_FLOW_CTL_EN; in sun8i_dwmac_flow_ctrl()
700 v &= ~EMAC_TX_FLOW_CTL_EN; in sun8i_dwmac_flow_ctrl()
701 writel(v, ioaddr + EMAC_TX_FLOW_CTL); in sun8i_dwmac_flow_ctrl()
706 u32 v; in sun8i_dwmac_reset() local
709 v = readl(priv->ioaddr + EMAC_BASIC_CTL1); in sun8i_dwmac_reset()
710 writel(v | 0x01, priv->ioaddr + EMAC_BASIC_CTL1); in sun8i_dwmac_reset()
713 * need more if no cable plugged. 100ms seems OK in sun8i_dwmac_reset()
715 err = readl_poll_timeout(priv->ioaddr + EMAC_BASIC_CTL1, v, in sun8i_dwmac_reset()
716 !(v & 0x01), 100, 100000); in sun8i_dwmac_reset()
719 dev_err(priv->device, "EMAC reset timeout\n"); in sun8i_dwmac_reset()
720 return -EFAULT; in sun8i_dwmac_reset()
725 /* Search in mdio-mux node for internal PHY node and get its clk/reset */
728 struct sunxi_priv_data *gmac = priv->plat->bsp_priv; in get_ephy_nodes()
733 mdio_mux = of_get_child_by_name(priv->device->of_node, "mdio-mux"); in get_ephy_nodes()
735 dev_err(priv->device, "Cannot get mdio-mux node\n"); in get_ephy_nodes()
736 return -ENODEV; in get_ephy_nodes()
740 "allwinner,sun8i-h3-mdio-internal"); in get_ephy_nodes()
743 dev_err(priv->device, "Cannot get internal_mdio node\n"); in get_ephy_nodes()
744 return -ENODEV; in get_ephy_nodes()
749 gmac->ephy_clk = of_clk_get(iphynode, 0); in get_ephy_nodes()
750 if (IS_ERR(gmac->ephy_clk)) in get_ephy_nodes()
752 gmac->rst_ephy = of_reset_control_get_exclusive(iphynode, NULL); in get_ephy_nodes()
753 if (IS_ERR(gmac->rst_ephy)) { in get_ephy_nodes()
754 ret = PTR_ERR(gmac->rst_ephy); in get_ephy_nodes()
755 if (ret == -EPROBE_DEFER) { in get_ephy_nodes()
762 dev_info(priv->device, "Found internal PHY node\n"); in get_ephy_nodes()
769 return -ENODEV; in get_ephy_nodes()
774 struct sunxi_priv_data *gmac = priv->plat->bsp_priv; in sun8i_dwmac_power_internal_phy()
777 if (gmac->internal_phy_powered) { in sun8i_dwmac_power_internal_phy()
778 dev_warn(priv->device, "Internal PHY already powered\n"); in sun8i_dwmac_power_internal_phy()
782 dev_info(priv->device, "Powering internal PHY\n"); in sun8i_dwmac_power_internal_phy()
783 ret = clk_prepare_enable(gmac->ephy_clk); in sun8i_dwmac_power_internal_phy()
785 dev_err(priv->device, "Cannot enable internal PHY\n"); in sun8i_dwmac_power_internal_phy()
789 /* Make sure the EPHY is properly reseted, as U-Boot may leave in sun8i_dwmac_power_internal_phy()
792 reset_control_assert(gmac->rst_ephy); in sun8i_dwmac_power_internal_phy()
794 ret = reset_control_deassert(gmac->rst_ephy); in sun8i_dwmac_power_internal_phy()
796 dev_err(priv->device, "Cannot deassert internal phy\n"); in sun8i_dwmac_power_internal_phy()
797 clk_disable_unprepare(gmac->ephy_clk); in sun8i_dwmac_power_internal_phy()
801 gmac->internal_phy_powered = true; in sun8i_dwmac_power_internal_phy()
808 if (!gmac->internal_phy_powered) in sun8i_dwmac_unpower_internal_phy()
811 clk_disable_unprepare(gmac->ephy_clk); in sun8i_dwmac_unpower_internal_phy()
812 reset_control_assert(gmac->rst_ephy); in sun8i_dwmac_unpower_internal_phy()
813 gmac->internal_phy_powered = false; in sun8i_dwmac_unpower_internal_phy()
818 * This function is called by the mdio-mux layer when it thinks the mdio bus
823 * The first time this function is called, current_child == -1.
831 struct sunxi_priv_data *gmac = priv->plat->bsp_priv; in mdio_mux_syscon_switch_fn()
837 regmap_field_read(gmac->regmap_field, &reg); in mdio_mux_syscon_switch_fn()
840 dev_info(priv->device, "Switch mux to internal PHY"); in mdio_mux_syscon_switch_fn()
846 dev_info(priv->device, "Switch mux to external PHY"); in mdio_mux_syscon_switch_fn()
851 dev_err(priv->device, "Invalid child ID %x\n", in mdio_mux_syscon_switch_fn()
853 return -EINVAL; in mdio_mux_syscon_switch_fn()
855 regmap_field_write(gmac->regmap_field, val); in mdio_mux_syscon_switch_fn()
875 struct sunxi_priv_data *gmac = priv->plat->bsp_priv; in sun8i_dwmac_register_mdio_mux()
877 mdio_mux = of_get_child_by_name(priv->device->of_node, "mdio-mux"); in sun8i_dwmac_register_mdio_mux()
879 return -ENODEV; in sun8i_dwmac_register_mdio_mux()
881 ret = mdio_mux_init(priv->device, mdio_mux, mdio_mux_syscon_switch_fn, in sun8i_dwmac_register_mdio_mux()
882 &gmac->mux_handle, priv, priv->mii); in sun8i_dwmac_register_mdio_mux()
888 struct sunxi_priv_data *gmac = priv->plat->bsp_priv; in sun8i_dwmac_set_syscon()
889 struct device_node *node = priv->device->of_node; in sun8i_dwmac_set_syscon()
893 ret = regmap_field_read(gmac->regmap_field, &val); in sun8i_dwmac_set_syscon()
895 dev_err(priv->device, "Fail to read from regmap field.\n"); in sun8i_dwmac_set_syscon()
899 reg = gmac->variant->default_syscon_value; in sun8i_dwmac_set_syscon()
901 dev_warn(priv->device, in sun8i_dwmac_set_syscon()
905 if (gmac->variant->soc_has_internal_phy) { in sun8i_dwmac_set_syscon()
906 if (of_property_read_bool(node, "allwinner,leds-active-low")) in sun8i_dwmac_set_syscon()
914 ret = of_mdio_parse_addr(priv->device, priv->plat->phy_node); in sun8i_dwmac_set_syscon()
916 dev_err(priv->device, "Could not parse MDIO addr\n"); in sun8i_dwmac_set_syscon()
920 * address. No need to mask it again. in sun8i_dwmac_set_syscon()
922 reg |= 1 << H3_EPHY_ADDR_SHIFT; in sun8i_dwmac_set_syscon()
930 if (!of_property_read_u32(node, "allwinner,tx-delay-ps", &val)) { in sun8i_dwmac_set_syscon()
932 dev_err(priv->device, "tx-delay must be a multiple of 100\n"); in sun8i_dwmac_set_syscon()
933 return -EINVAL; in sun8i_dwmac_set_syscon()
936 dev_dbg(priv->device, "set tx-delay to %x\n", val); in sun8i_dwmac_set_syscon()
937 if (val <= gmac->variant->tx_delay_max) { in sun8i_dwmac_set_syscon()
938 reg &= ~(gmac->variant->tx_delay_max << in sun8i_dwmac_set_syscon()
942 dev_err(priv->device, "Invalid TX clock delay: %d\n", in sun8i_dwmac_set_syscon()
944 return -EINVAL; in sun8i_dwmac_set_syscon()
948 if (!of_property_read_u32(node, "allwinner,rx-delay-ps", &val)) { in sun8i_dwmac_set_syscon()
950 dev_err(priv->device, "rx-delay must be a multiple of 100\n"); in sun8i_dwmac_set_syscon()
951 return -EINVAL; in sun8i_dwmac_set_syscon()
954 dev_dbg(priv->device, "set rx-delay to %x\n", val); in sun8i_dwmac_set_syscon()
955 if (val <= gmac->variant->rx_delay_max) { in sun8i_dwmac_set_syscon()
956 reg &= ~(gmac->variant->rx_delay_max << in sun8i_dwmac_set_syscon()
960 dev_err(priv->device, "Invalid RX clock delay: %d\n", in sun8i_dwmac_set_syscon()
962 return -EINVAL; in sun8i_dwmac_set_syscon()
968 if (gmac->variant->support_rmii) in sun8i_dwmac_set_syscon()
971 switch (priv->plat->interface) { in sun8i_dwmac_set_syscon()
985 dev_err(priv->device, "Unsupported interface mode: %s", in sun8i_dwmac_set_syscon()
986 phy_modes(priv->plat->interface)); in sun8i_dwmac_set_syscon()
987 return -EINVAL; in sun8i_dwmac_set_syscon()
990 regmap_field_write(gmac->regmap_field, reg); in sun8i_dwmac_set_syscon()
997 u32 reg = gmac->variant->default_syscon_value; in sun8i_dwmac_unset_syscon()
999 regmap_field_write(gmac->regmap_field, reg); in sun8i_dwmac_unset_syscon()
1006 if (gmac->variant->soc_has_internal_phy) { in sun8i_dwmac_exit()
1008 if (gmac->mux_handle) in sun8i_dwmac_exit()
1009 mdio_mux_uninit(gmac->mux_handle); in sun8i_dwmac_exit()
1010 if (gmac->internal_phy_powered) in sun8i_dwmac_exit()
1016 reset_control_put(gmac->rst_ephy); in sun8i_dwmac_exit()
1018 clk_disable_unprepare(gmac->tx_clk); in sun8i_dwmac_exit()
1020 if (gmac->regulator) in sun8i_dwmac_exit()
1021 regulator_disable(gmac->regulator); in sun8i_dwmac_exit()
1054 mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL); in sun8i_dwmac_setup()
1062 mac->pcsr = priv->ioaddr; in sun8i_dwmac_setup()
1063 mac->mac = &sun8i_dwmac_ops; in sun8i_dwmac_setup()
1064 mac->dma = &sun8i_dwmac_dma_ops; in sun8i_dwmac_setup()
1066 priv->dev->priv_flags |= IFF_UNICAST_FLT; in sun8i_dwmac_setup()
1068 /* The loopback bit seems to be re-set when link change in sun8i_dwmac_setup()
1072 mac->link.speed_mask = GENMASK(3, 2) | EMAC_LOOPBACK; in sun8i_dwmac_setup()
1073 mac->link.speed10 = EMAC_SPEED_10; in sun8i_dwmac_setup()
1074 mac->link.speed100 = EMAC_SPEED_100; in sun8i_dwmac_setup()
1075 mac->link.speed1000 = EMAC_SPEED_1000; in sun8i_dwmac_setup()
1076 mac->link.duplex = EMAC_DUPLEX_FULL; in sun8i_dwmac_setup()
1077 mac->mii.addr = EMAC_MDIO_CMD; in sun8i_dwmac_setup()
1078 mac->mii.data = EMAC_MDIO_DATA; in sun8i_dwmac_setup()
1079 mac->mii.reg_shift = 4; in sun8i_dwmac_setup()
1080 mac->mii.reg_mask = GENMASK(8, 4); in sun8i_dwmac_setup()
1081 mac->mii.addr_shift = 12; in sun8i_dwmac_setup()
1082 mac->mii.addr_mask = GENMASK(16, 12); in sun8i_dwmac_setup()
1083 mac->mii.clk_csr_shift = 20; in sun8i_dwmac_setup()
1084 mac->mii.clk_csr_mask = GENMASK(22, 20); in sun8i_dwmac_setup()
1085 mac->unicast_filter_entries = 8; in sun8i_dwmac_setup()
1088 priv->synopsys_id = 0; in sun8i_dwmac_setup()
1101 return ERR_PTR(-ENODEV); in sun8i_dwmac_get_syscon_from_dev()
1106 regmap = ERR_PTR(-EPROBE_DEFER); in sun8i_dwmac_get_syscon_from_dev()
1110 /* If no regmap is found then the other device driver is at fault */ in sun8i_dwmac_get_syscon_from_dev()
1111 regmap = dev_get_regmap(&syscon_pdev->dev, NULL); in sun8i_dwmac_get_syscon_from_dev()
1113 regmap = ERR_PTR(-EINVAL); in sun8i_dwmac_get_syscon_from_dev()
1126 struct device *dev = &pdev->dev; in sun8i_dwmac_probe()
1143 return -ENOMEM; in sun8i_dwmac_probe()
1145 gmac->variant = of_device_get_match_data(&pdev->dev); in sun8i_dwmac_probe()
1146 if (!gmac->variant) { in sun8i_dwmac_probe()
1147 dev_err(&pdev->dev, "Missing dwmac-sun8i variant\n"); in sun8i_dwmac_probe()
1148 return -EINVAL; in sun8i_dwmac_probe()
1151 gmac->tx_clk = devm_clk_get(dev, "stmmaceth"); in sun8i_dwmac_probe()
1152 if (IS_ERR(gmac->tx_clk)) { in sun8i_dwmac_probe()
1154 return PTR_ERR(gmac->tx_clk); in sun8i_dwmac_probe()
1158 gmac->regulator = devm_regulator_get_optional(dev, "phy"); in sun8i_dwmac_probe()
1159 if (IS_ERR(gmac->regulator)) { in sun8i_dwmac_probe()
1160 if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER) in sun8i_dwmac_probe()
1161 return -EPROBE_DEFER; in sun8i_dwmac_probe()
1162 dev_info(dev, "No regulator found\n"); in sun8i_dwmac_probe()
1163 gmac->regulator = NULL; in sun8i_dwmac_probe()
1183 regmap = sun8i_dwmac_get_syscon_from_dev(pdev->dev.of_node); in sun8i_dwmac_probe()
1185 regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, in sun8i_dwmac_probe()
1189 dev_err(&pdev->dev, "Unable to map syscon: %d\n", ret); in sun8i_dwmac_probe()
1193 gmac->regmap_field = devm_regmap_field_alloc(dev, regmap, in sun8i_dwmac_probe()
1194 *gmac->variant->syscon_field); in sun8i_dwmac_probe()
1195 if (IS_ERR(gmac->regmap_field)) { in sun8i_dwmac_probe()
1196 ret = PTR_ERR(gmac->regmap_field); in sun8i_dwmac_probe()
1201 ret = of_get_phy_mode(dev->of_node, &interface); in sun8i_dwmac_probe()
1203 return -EINVAL; in sun8i_dwmac_probe()
1204 plat_dat->interface = interface; in sun8i_dwmac_probe()
1209 plat_dat->rx_coe = STMMAC_RX_COE_TYPE2; in sun8i_dwmac_probe()
1210 plat_dat->tx_coe = 1; in sun8i_dwmac_probe()
1211 plat_dat->has_sun8i = true; in sun8i_dwmac_probe()
1212 plat_dat->bsp_priv = gmac; in sun8i_dwmac_probe()
1213 plat_dat->init = sun8i_dwmac_init; in sun8i_dwmac_probe()
1214 plat_dat->exit = sun8i_dwmac_exit; in sun8i_dwmac_probe()
1215 plat_dat->setup = sun8i_dwmac_setup; in sun8i_dwmac_probe()
1217 ret = sun8i_dwmac_init(pdev, plat_dat->bsp_priv); in sun8i_dwmac_probe()
1221 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); in sun8i_dwmac_probe()
1225 ndev = dev_get_drvdata(&pdev->dev); in sun8i_dwmac_probe()
1230 if (gmac->variant->soc_has_internal_phy) { in sun8i_dwmac_probe()
1236 dev_err(&pdev->dev, "Failed to register mux\n"); in sun8i_dwmac_probe()
1254 { .compatible = "allwinner,sun8i-h3-emac",
1256 { .compatible = "allwinner,sun8i-v3s-emac",
1258 { .compatible = "allwinner,sun8i-a83t-emac",
1260 { .compatible = "allwinner,sun8i-r40-gmac",
1262 { .compatible = "allwinner,sun50i-a64-emac",
1264 { .compatible = "allwinner,sun50i-h6-emac",
1274 .name = "dwmac-sun8i",