Lines Matching +full:v +full:- +full:bit
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>
27 /* General notes on dwmac-sun8i:
32 /* struct emac_variant - Describe dwmac-sun8i hardware variant
60 /* struct sunxi_priv_data - hold all sunxi private data
68 * @mux_handle: Internal pointer used by mdio-mux lib
146 * co-packaged AC200 chip instead.
180 #define EMAC_DUPLEX_FULL BIT(0)
181 #define EMAC_LOOPBACK BIT(1)
190 #define EMAC_FRM_FLT_RXALL BIT(0)
191 #define EMAC_FRM_FLT_CTL BIT(13)
192 #define EMAC_FRM_FLT_MULTICAST BIT(16)
195 #define EMAC_RX_MD BIT(1)
201 #define EMAC_RX_DMA_EN BIT(30)
202 #define EMAC_RX_DMA_START BIT(31)
205 #define EMAC_TX_MD BIT(1)
206 #define EMAC_TX_NEXT_FRM BIT(2)
212 #define EMAC_TX_DMA_EN BIT(30)
213 #define EMAC_TX_DMA_START BIT(31)
216 #define EMAC_RX_RECEIVER_EN BIT(31)
217 #define EMAC_RX_DO_CRC BIT(27)
218 #define EMAC_RX_FLOW_CTL_EN BIT(16)
221 #define EMAC_TX_TRANSMITTER_EN BIT(31)
224 #define EMAC_TX_FLOW_CTL_EN BIT(0)
227 #define EMAC_TX_INT BIT(0)
228 #define EMAC_TX_DMA_STOP_INT BIT(1)
229 #define EMAC_TX_BUF_UA_INT BIT(2)
230 #define EMAC_TX_TIMEOUT_INT BIT(3)
231 #define EMAC_TX_UNDERFLOW_INT BIT(4)
232 #define EMAC_TX_EARLY_INT BIT(5)
233 #define EMAC_RX_INT BIT(8)
234 #define EMAC_RX_BUF_UA_INT BIT(9)
235 #define EMAC_RX_DMA_STOP_INT BIT(10)
236 #define EMAC_RX_TIMEOUT_INT BIT(11)
237 #define EMAC_RX_OVERFLOW_INT BIT(12)
238 #define EMAC_RX_EARLY_INT BIT(13)
239 #define EMAC_RGMII_STA_INT BIT(16)
257 #define MAC_ADDR_TYPE_DST BIT(31)
261 #define H3_EPHY_CLK_SEL BIT(18) /* 1: 24MHz, 0: 25MHz */
262 #define H3_EPHY_LED_POL BIT(17) /* 1: active low, 0: active high */
263 #define H3_EPHY_SHUTDOWN BIT(16) /* 1: shutdown, 0: power up */
264 #define H3_EPHY_SELECT BIT(15) /* 1: internal PHY, 0: external PHY */
270 #define SYSCON_RMII_EN BIT(13) /* 1: enable RMII (overrides EPIT) */
276 #define SYSCON_EPIT BIT(2) /* 1: RGMII, 0: MII */
282 /* sun8i_dwmac_dma_reset() - reset the EMAC
283 * Called from stmmac via stmmac_dma_ops->reset
297 /* sun8i_dwmac_dma_init() - initialize the EMAC
298 * Called from stmmac via stmmac_dma_ops->init
323 /* sun8i_dwmac_dump_regs() - Dump EMAC address space
324 * Called from stmmac_dma_ops->dump_regs
338 /* sun8i_dwmac_dump_mac_regs() - Dump EMAC address space
339 * Called from stmmac_ops->dump_regs
346 void __iomem *ioaddr = hw->pcsr; in sun8i_dwmac_dump_mac_regs()
383 u32 v; in sun8i_dwmac_dma_start_tx() local
385 v = readl(ioaddr + EMAC_TX_CTL1); in sun8i_dwmac_dma_start_tx()
386 v |= EMAC_TX_DMA_START; in sun8i_dwmac_dma_start_tx()
387 v |= EMAC_TX_DMA_EN; in sun8i_dwmac_dma_start_tx()
388 writel(v, ioaddr + EMAC_TX_CTL1); in sun8i_dwmac_dma_start_tx()
393 u32 v; in sun8i_dwmac_enable_dma_transmission() local
395 v = readl(ioaddr + EMAC_TX_CTL1); in sun8i_dwmac_enable_dma_transmission()
396 v |= EMAC_TX_DMA_START; in sun8i_dwmac_enable_dma_transmission()
397 v |= EMAC_TX_DMA_EN; in sun8i_dwmac_enable_dma_transmission()
398 writel(v, ioaddr + EMAC_TX_CTL1); in sun8i_dwmac_enable_dma_transmission()
403 u32 v; in sun8i_dwmac_dma_stop_tx() local
405 v = readl(ioaddr + EMAC_TX_CTL1); in sun8i_dwmac_dma_stop_tx()
406 v &= ~EMAC_TX_DMA_EN; in sun8i_dwmac_dma_stop_tx()
407 writel(v, ioaddr + EMAC_TX_CTL1); in sun8i_dwmac_dma_stop_tx()
412 u32 v; in sun8i_dwmac_dma_start_rx() local
414 v = readl(ioaddr + EMAC_RX_CTL1); in sun8i_dwmac_dma_start_rx()
415 v |= EMAC_RX_DMA_START; in sun8i_dwmac_dma_start_rx()
416 v |= EMAC_RX_DMA_EN; in sun8i_dwmac_dma_start_rx()
417 writel(v, ioaddr + EMAC_RX_CTL1); in sun8i_dwmac_dma_start_rx()
422 u32 v; in sun8i_dwmac_dma_stop_rx() local
424 v = readl(ioaddr + EMAC_RX_CTL1); in sun8i_dwmac_dma_stop_rx()
425 v &= ~EMAC_RX_DMA_EN; in sun8i_dwmac_dma_stop_rx()
426 writel(v, ioaddr + EMAC_RX_CTL1); in sun8i_dwmac_dma_stop_rx()
433 u32 v; in sun8i_dwmac_dma_interrupt() local
436 v = readl(ioaddr + EMAC_INT_STA); in sun8i_dwmac_dma_interrupt()
439 v &= EMAC_INT_MSK_RX; in sun8i_dwmac_dma_interrupt()
441 v &= EMAC_INT_MSK_TX; in sun8i_dwmac_dma_interrupt()
443 if (v & EMAC_TX_INT) { in sun8i_dwmac_dma_interrupt()
445 x->tx_normal_irq_n++; in sun8i_dwmac_dma_interrupt()
448 if (v & EMAC_TX_DMA_STOP_INT) in sun8i_dwmac_dma_interrupt()
449 x->tx_process_stopped_irq++; in sun8i_dwmac_dma_interrupt()
451 if (v & EMAC_TX_BUF_UA_INT) in sun8i_dwmac_dma_interrupt()
452 x->tx_process_stopped_irq++; in sun8i_dwmac_dma_interrupt()
454 if (v & EMAC_TX_TIMEOUT_INT) in sun8i_dwmac_dma_interrupt()
457 if (v & EMAC_TX_UNDERFLOW_INT) { in sun8i_dwmac_dma_interrupt()
459 x->tx_undeflow_irq++; in sun8i_dwmac_dma_interrupt()
462 if (v & EMAC_TX_EARLY_INT) in sun8i_dwmac_dma_interrupt()
463 x->tx_early_irq++; in sun8i_dwmac_dma_interrupt()
465 if (v & EMAC_RX_INT) { in sun8i_dwmac_dma_interrupt()
467 x->rx_normal_irq_n++; in sun8i_dwmac_dma_interrupt()
470 if (v & EMAC_RX_BUF_UA_INT) in sun8i_dwmac_dma_interrupt()
471 x->rx_buf_unav_irq++; in sun8i_dwmac_dma_interrupt()
473 if (v & EMAC_RX_DMA_STOP_INT) in sun8i_dwmac_dma_interrupt()
474 x->rx_process_stopped_irq++; in sun8i_dwmac_dma_interrupt()
476 if (v & EMAC_RX_TIMEOUT_INT) in sun8i_dwmac_dma_interrupt()
479 if (v & EMAC_RX_OVERFLOW_INT) { in sun8i_dwmac_dma_interrupt()
481 x->rx_overflow_irq++; in sun8i_dwmac_dma_interrupt()
484 if (v & EMAC_RX_EARLY_INT) in sun8i_dwmac_dma_interrupt()
485 x->rx_early_irq++; in sun8i_dwmac_dma_interrupt()
487 if (v & EMAC_RGMII_STA_INT) in sun8i_dwmac_dma_interrupt()
488 x->irq_rgmii_n++; in sun8i_dwmac_dma_interrupt()
490 writel(v, ioaddr + EMAC_INT_STA); in sun8i_dwmac_dma_interrupt()
498 u32 v; in sun8i_dwmac_dma_operation_mode_rx() local
500 v = readl(ioaddr + EMAC_RX_CTL1); in sun8i_dwmac_dma_operation_mode_rx()
502 v |= EMAC_RX_MD; in sun8i_dwmac_dma_operation_mode_rx()
504 v &= ~EMAC_RX_MD; in sun8i_dwmac_dma_operation_mode_rx()
505 v &= ~EMAC_RX_TH_MASK; in sun8i_dwmac_dma_operation_mode_rx()
507 v |= EMAC_RX_TH_32; in sun8i_dwmac_dma_operation_mode_rx()
509 v |= EMAC_RX_TH_64; in sun8i_dwmac_dma_operation_mode_rx()
511 v |= EMAC_RX_TH_96; in sun8i_dwmac_dma_operation_mode_rx()
513 v |= EMAC_RX_TH_128; in sun8i_dwmac_dma_operation_mode_rx()
515 writel(v, ioaddr + EMAC_RX_CTL1); in sun8i_dwmac_dma_operation_mode_rx()
521 u32 v; in sun8i_dwmac_dma_operation_mode_tx() local
523 v = readl(ioaddr + EMAC_TX_CTL1); in sun8i_dwmac_dma_operation_mode_tx()
525 v |= EMAC_TX_MD; in sun8i_dwmac_dma_operation_mode_tx()
526 /* Undocumented bit (called TX_NEXT_FRM in BSP), the original in sun8i_dwmac_dma_operation_mode_tx()
529 * especially when transmit store-and-forward is used." in sun8i_dwmac_dma_operation_mode_tx()
531 v |= EMAC_TX_NEXT_FRM; in sun8i_dwmac_dma_operation_mode_tx()
533 v &= ~EMAC_TX_MD; in sun8i_dwmac_dma_operation_mode_tx()
534 v &= ~EMAC_TX_TH_MASK; in sun8i_dwmac_dma_operation_mode_tx()
536 v |= EMAC_TX_TH_64; in sun8i_dwmac_dma_operation_mode_tx()
538 v |= EMAC_TX_TH_128; in sun8i_dwmac_dma_operation_mode_tx()
540 v |= EMAC_TX_TH_192; in sun8i_dwmac_dma_operation_mode_tx()
542 v |= EMAC_TX_TH_256; in sun8i_dwmac_dma_operation_mode_tx()
544 writel(v, ioaddr + EMAC_TX_CTL1); in sun8i_dwmac_dma_operation_mode_tx()
573 if (gmac->regulator) { in sun8i_dwmac_init()
574 ret = regulator_enable(gmac->regulator); in sun8i_dwmac_init()
576 dev_err(&pdev->dev, "Fail to enable regulator\n"); in sun8i_dwmac_init()
581 if (gmac->use_internal_phy) { in sun8i_dwmac_init()
590 if (gmac->regulator) in sun8i_dwmac_init()
591 regulator_disable(gmac->regulator); in sun8i_dwmac_init()
599 void __iomem *ioaddr = hw->pcsr; in sun8i_dwmac_core_init()
600 u32 v; in sun8i_dwmac_core_init() local
602 v = (8 << EMAC_BURSTLEN_SHIFT); /* burst len */ in sun8i_dwmac_core_init()
603 writel(v, ioaddr + EMAC_BASIC_CTL1); in sun8i_dwmac_core_init()
631 void __iomem *ioaddr = hw->pcsr; in sun8i_dwmac_set_umac_addr()
632 u32 v; in sun8i_dwmac_set_umac_addr() local
642 v = readl(ioaddr + EMAC_MACADDR_HI(reg_n)); in sun8i_dwmac_set_umac_addr()
643 v |= MAC_ADDR_TYPE_DST; in sun8i_dwmac_set_umac_addr()
644 writel(v, ioaddr + EMAC_MACADDR_HI(reg_n)); in sun8i_dwmac_set_umac_addr()
652 void __iomem *ioaddr = hw->pcsr; in sun8i_dwmac_get_umac_addr()
661 void __iomem *ioaddr = hw->pcsr; in sun8i_dwmac_rx_ipc_enable()
662 u32 v; in sun8i_dwmac_rx_ipc_enable() local
664 v = readl(ioaddr + EMAC_RX_CTL0); in sun8i_dwmac_rx_ipc_enable()
665 v |= EMAC_RX_DO_CRC; in sun8i_dwmac_rx_ipc_enable()
666 writel(v, ioaddr + EMAC_RX_CTL0); in sun8i_dwmac_rx_ipc_enable()
674 void __iomem *ioaddr = hw->pcsr; in sun8i_dwmac_set_filter()
675 u32 v; in sun8i_dwmac_set_filter() local
680 v = EMAC_FRM_FLT_CTL; in sun8i_dwmac_set_filter()
682 if (dev->flags & IFF_PROMISC) { in sun8i_dwmac_set_filter()
683 v = EMAC_FRM_FLT_RXALL; in sun8i_dwmac_set_filter()
684 } else if (dev->flags & IFF_ALLMULTI) { in sun8i_dwmac_set_filter()
685 v |= EMAC_FRM_FLT_MULTICAST; in sun8i_dwmac_set_filter()
686 } else if (macaddrs <= hw->unicast_filter_entries) { in sun8i_dwmac_set_filter()
689 sun8i_dwmac_set_umac_addr(hw, ha->addr, i); in sun8i_dwmac_set_filter()
695 sun8i_dwmac_set_umac_addr(hw, ha->addr, i); in sun8i_dwmac_set_filter()
702 v = EMAC_FRM_FLT_RXALL; in sun8i_dwmac_set_filter()
706 while (i < hw->unicast_filter_entries) in sun8i_dwmac_set_filter()
709 writel(v, ioaddr + EMAC_RX_FRM_FLT); in sun8i_dwmac_set_filter()
716 void __iomem *ioaddr = hw->pcsr; in sun8i_dwmac_flow_ctrl()
717 u32 v; in sun8i_dwmac_flow_ctrl() local
719 v = readl(ioaddr + EMAC_RX_CTL0); in sun8i_dwmac_flow_ctrl()
721 v |= EMAC_RX_FLOW_CTL_EN; in sun8i_dwmac_flow_ctrl()
723 v &= ~EMAC_RX_FLOW_CTL_EN; in sun8i_dwmac_flow_ctrl()
724 writel(v, ioaddr + EMAC_RX_CTL0); in sun8i_dwmac_flow_ctrl()
726 v = readl(ioaddr + EMAC_TX_FLOW_CTL); in sun8i_dwmac_flow_ctrl()
728 v |= EMAC_TX_FLOW_CTL_EN; in sun8i_dwmac_flow_ctrl()
730 v &= ~EMAC_TX_FLOW_CTL_EN; in sun8i_dwmac_flow_ctrl()
731 writel(v, ioaddr + EMAC_TX_FLOW_CTL); in sun8i_dwmac_flow_ctrl()
736 u32 v; in sun8i_dwmac_reset() local
739 v = readl(priv->ioaddr + EMAC_BASIC_CTL1); in sun8i_dwmac_reset()
740 writel(v | 0x01, priv->ioaddr + EMAC_BASIC_CTL1); in sun8i_dwmac_reset()
745 err = readl_poll_timeout(priv->ioaddr + EMAC_BASIC_CTL1, v, in sun8i_dwmac_reset()
746 !(v & 0x01), 100, 100000); in sun8i_dwmac_reset()
749 dev_err(priv->device, "EMAC reset timeout\n"); in sun8i_dwmac_reset()
755 /* Search in mdio-mux node for internal PHY node and get its clk/reset */
758 struct sunxi_priv_data *gmac = priv->plat->bsp_priv; in get_ephy_nodes()
763 mdio_mux = of_get_child_by_name(priv->device->of_node, "mdio-mux"); in get_ephy_nodes()
765 dev_err(priv->device, "Cannot get mdio-mux node\n"); in get_ephy_nodes()
766 return -ENODEV; in get_ephy_nodes()
770 "allwinner,sun8i-h3-mdio-internal"); in get_ephy_nodes()
773 dev_err(priv->device, "Cannot get internal_mdio node\n"); in get_ephy_nodes()
774 return -ENODEV; in get_ephy_nodes()
779 gmac->ephy_clk = of_clk_get(iphynode, 0); in get_ephy_nodes()
780 if (IS_ERR(gmac->ephy_clk)) in get_ephy_nodes()
782 gmac->rst_ephy = of_reset_control_get_exclusive(iphynode, NULL); in get_ephy_nodes()
783 if (IS_ERR(gmac->rst_ephy)) { in get_ephy_nodes()
784 ret = PTR_ERR(gmac->rst_ephy); in get_ephy_nodes()
785 if (ret == -EPROBE_DEFER) { in get_ephy_nodes()
792 dev_info(priv->device, "Found internal PHY node\n"); in get_ephy_nodes()
799 return -ENODEV; in get_ephy_nodes()
804 struct sunxi_priv_data *gmac = priv->plat->bsp_priv; in sun8i_dwmac_power_internal_phy()
807 if (gmac->internal_phy_powered) { in sun8i_dwmac_power_internal_phy()
808 dev_warn(priv->device, "Internal PHY already powered\n"); in sun8i_dwmac_power_internal_phy()
812 dev_info(priv->device, "Powering internal PHY\n"); in sun8i_dwmac_power_internal_phy()
813 ret = clk_prepare_enable(gmac->ephy_clk); in sun8i_dwmac_power_internal_phy()
815 dev_err(priv->device, "Cannot enable internal PHY\n"); in sun8i_dwmac_power_internal_phy()
819 /* Make sure the EPHY is properly reseted, as U-Boot may leave in sun8i_dwmac_power_internal_phy()
824 ret = reset_control_reset(gmac->rst_ephy); in sun8i_dwmac_power_internal_phy()
826 dev_err(priv->device, "Cannot reset internal PHY\n"); in sun8i_dwmac_power_internal_phy()
827 clk_disable_unprepare(gmac->ephy_clk); in sun8i_dwmac_power_internal_phy()
831 gmac->internal_phy_powered = true; in sun8i_dwmac_power_internal_phy()
838 if (!gmac->internal_phy_powered) in sun8i_dwmac_unpower_internal_phy()
841 clk_disable_unprepare(gmac->ephy_clk); in sun8i_dwmac_unpower_internal_phy()
842 reset_control_assert(gmac->rst_ephy); in sun8i_dwmac_unpower_internal_phy()
843 gmac->internal_phy_powered = false; in sun8i_dwmac_unpower_internal_phy()
847 * This function is called by the mdio-mux layer when it thinks the mdio bus
852 * The first time this function is called, current_child == -1.
860 struct sunxi_priv_data *gmac = priv->plat->bsp_priv; in mdio_mux_syscon_switch_fn()
865 regmap_field_read(gmac->regmap_field, ®); in mdio_mux_syscon_switch_fn()
868 dev_info(priv->device, "Switch mux to internal PHY"); in mdio_mux_syscon_switch_fn()
870 gmac->use_internal_phy = true; in mdio_mux_syscon_switch_fn()
873 dev_info(priv->device, "Switch mux to external PHY"); in mdio_mux_syscon_switch_fn()
875 gmac->use_internal_phy = false; in mdio_mux_syscon_switch_fn()
878 dev_err(priv->device, "Invalid child ID %x\n", in mdio_mux_syscon_switch_fn()
880 return -EINVAL; in mdio_mux_syscon_switch_fn()
882 regmap_field_write(gmac->regmap_field, val); in mdio_mux_syscon_switch_fn()
883 if (gmac->use_internal_phy) { in mdio_mux_syscon_switch_fn()
902 struct sunxi_priv_data *gmac = priv->plat->bsp_priv; in sun8i_dwmac_register_mdio_mux()
904 mdio_mux = of_get_child_by_name(priv->device->of_node, "mdio-mux"); in sun8i_dwmac_register_mdio_mux()
906 return -ENODEV; in sun8i_dwmac_register_mdio_mux()
908 ret = mdio_mux_init(priv->device, mdio_mux, mdio_mux_syscon_switch_fn, in sun8i_dwmac_register_mdio_mux()
909 &gmac->mux_handle, priv, priv->mii); in sun8i_dwmac_register_mdio_mux()
917 struct sunxi_priv_data *gmac = plat->bsp_priv; in sun8i_dwmac_set_syscon()
918 struct device_node *node = dev->of_node; in sun8i_dwmac_set_syscon()
922 ret = regmap_field_read(gmac->regmap_field, &val); in sun8i_dwmac_set_syscon()
928 reg = gmac->variant->default_syscon_value; in sun8i_dwmac_set_syscon()
934 if (gmac->variant->soc_has_internal_phy) { in sun8i_dwmac_set_syscon()
935 if (of_property_read_bool(node, "allwinner,leds-active-low")) in sun8i_dwmac_set_syscon()
943 ret = of_mdio_parse_addr(dev, plat->phy_node); in sun8i_dwmac_set_syscon()
953 /* For SoCs without internal PHY the PHY selection bit should be in sun8i_dwmac_set_syscon()
959 if (!of_property_read_u32(node, "allwinner,tx-delay-ps", &val)) { in sun8i_dwmac_set_syscon()
961 dev_err(dev, "tx-delay must be a multiple of 100\n"); in sun8i_dwmac_set_syscon()
962 return -EINVAL; in sun8i_dwmac_set_syscon()
965 dev_dbg(dev, "set tx-delay to %x\n", val); in sun8i_dwmac_set_syscon()
966 if (val <= gmac->variant->tx_delay_max) { in sun8i_dwmac_set_syscon()
967 reg &= ~(gmac->variant->tx_delay_max << in sun8i_dwmac_set_syscon()
973 return -EINVAL; in sun8i_dwmac_set_syscon()
977 if (!of_property_read_u32(node, "allwinner,rx-delay-ps", &val)) { in sun8i_dwmac_set_syscon()
979 dev_err(dev, "rx-delay must be a multiple of 100\n"); in sun8i_dwmac_set_syscon()
980 return -EINVAL; in sun8i_dwmac_set_syscon()
983 dev_dbg(dev, "set rx-delay to %x\n", val); in sun8i_dwmac_set_syscon()
984 if (val <= gmac->variant->rx_delay_max) { in sun8i_dwmac_set_syscon()
985 reg &= ~(gmac->variant->rx_delay_max << in sun8i_dwmac_set_syscon()
991 return -EINVAL; in sun8i_dwmac_set_syscon()
997 if (gmac->variant->support_rmii) in sun8i_dwmac_set_syscon()
1000 switch (plat->interface) { in sun8i_dwmac_set_syscon()
1015 phy_modes(plat->interface)); in sun8i_dwmac_set_syscon()
1016 return -EINVAL; in sun8i_dwmac_set_syscon()
1019 regmap_field_write(gmac->regmap_field, reg); in sun8i_dwmac_set_syscon()
1026 u32 reg = gmac->variant->default_syscon_value; in sun8i_dwmac_unset_syscon()
1028 regmap_field_write(gmac->regmap_field, reg); in sun8i_dwmac_unset_syscon()
1035 if (gmac->variant->soc_has_internal_phy) in sun8i_dwmac_exit()
1038 if (gmac->regulator) in sun8i_dwmac_exit()
1039 regulator_disable(gmac->regulator); in sun8i_dwmac_exit()
1071 mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL); in sun8i_dwmac_setup()
1075 mac->pcsr = priv->ioaddr; in sun8i_dwmac_setup()
1076 mac->mac = &sun8i_dwmac_ops; in sun8i_dwmac_setup()
1077 mac->dma = &sun8i_dwmac_dma_ops; in sun8i_dwmac_setup()
1079 priv->dev->priv_flags |= IFF_UNICAST_FLT; in sun8i_dwmac_setup()
1081 /* The loopback bit seems to be re-set when link change in sun8i_dwmac_setup()
1083 * Speed 10/100/1000 are set in BIT(2)/BIT(3) in sun8i_dwmac_setup()
1085 mac->link.speed_mask = GENMASK(3, 2) | EMAC_LOOPBACK; in sun8i_dwmac_setup()
1086 mac->link.speed10 = EMAC_SPEED_10; in sun8i_dwmac_setup()
1087 mac->link.speed100 = EMAC_SPEED_100; in sun8i_dwmac_setup()
1088 mac->link.speed1000 = EMAC_SPEED_1000; in sun8i_dwmac_setup()
1089 mac->link.duplex = EMAC_DUPLEX_FULL; in sun8i_dwmac_setup()
1090 mac->mii.addr = EMAC_MDIO_CMD; in sun8i_dwmac_setup()
1091 mac->mii.data = EMAC_MDIO_DATA; in sun8i_dwmac_setup()
1092 mac->mii.reg_shift = 4; in sun8i_dwmac_setup()
1093 mac->mii.reg_mask = GENMASK(8, 4); in sun8i_dwmac_setup()
1094 mac->mii.addr_shift = 12; in sun8i_dwmac_setup()
1095 mac->mii.addr_mask = GENMASK(16, 12); in sun8i_dwmac_setup()
1096 mac->mii.clk_csr_shift = 20; in sun8i_dwmac_setup()
1097 mac->mii.clk_csr_mask = GENMASK(22, 20); in sun8i_dwmac_setup()
1098 mac->unicast_filter_entries = 8; in sun8i_dwmac_setup()
1101 priv->synopsys_id = 0; in sun8i_dwmac_setup()
1114 return ERR_PTR(-ENODEV); in sun8i_dwmac_get_syscon_from_dev()
1119 regmap = ERR_PTR(-EPROBE_DEFER); in sun8i_dwmac_get_syscon_from_dev()
1124 regmap = dev_get_regmap(&syscon_pdev->dev, NULL); in sun8i_dwmac_get_syscon_from_dev()
1126 regmap = ERR_PTR(-EINVAL); in sun8i_dwmac_get_syscon_from_dev()
1139 struct device *dev = &pdev->dev; in sun8i_dwmac_probe()
1152 return -ENOMEM; in sun8i_dwmac_probe()
1154 gmac->variant = of_device_get_match_data(&pdev->dev); in sun8i_dwmac_probe()
1155 if (!gmac->variant) { in sun8i_dwmac_probe()
1156 dev_err(&pdev->dev, "Missing dwmac-sun8i variant\n"); in sun8i_dwmac_probe()
1157 return -EINVAL; in sun8i_dwmac_probe()
1161 gmac->regulator = devm_regulator_get_optional(dev, "phy"); in sun8i_dwmac_probe()
1162 if (IS_ERR(gmac->regulator)) { in sun8i_dwmac_probe()
1163 if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER) in sun8i_dwmac_probe()
1164 return -EPROBE_DEFER; in sun8i_dwmac_probe()
1166 gmac->regulator = NULL; in sun8i_dwmac_probe()
1186 regmap = sun8i_dwmac_get_syscon_from_dev(pdev->dev.of_node); in sun8i_dwmac_probe()
1188 regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, in sun8i_dwmac_probe()
1192 dev_err(&pdev->dev, "Unable to map syscon: %d\n", ret); in sun8i_dwmac_probe()
1196 gmac->regmap_field = devm_regmap_field_alloc(dev, regmap, in sun8i_dwmac_probe()
1197 *gmac->variant->syscon_field); in sun8i_dwmac_probe()
1198 if (IS_ERR(gmac->regmap_field)) { in sun8i_dwmac_probe()
1199 ret = PTR_ERR(gmac->regmap_field); in sun8i_dwmac_probe()
1204 ret = of_get_phy_mode(dev->of_node, &interface); in sun8i_dwmac_probe()
1206 return -EINVAL; in sun8i_dwmac_probe()
1215 plat_dat->interface = interface; in sun8i_dwmac_probe()
1216 plat_dat->rx_coe = STMMAC_RX_COE_TYPE2; in sun8i_dwmac_probe()
1217 plat_dat->tx_coe = 1; in sun8i_dwmac_probe()
1218 plat_dat->has_sun8i = true; in sun8i_dwmac_probe()
1219 plat_dat->bsp_priv = gmac; in sun8i_dwmac_probe()
1220 plat_dat->init = sun8i_dwmac_init; in sun8i_dwmac_probe()
1221 plat_dat->exit = sun8i_dwmac_exit; in sun8i_dwmac_probe()
1222 plat_dat->setup = sun8i_dwmac_setup; in sun8i_dwmac_probe()
1223 plat_dat->tx_fifo_size = 4096; in sun8i_dwmac_probe()
1224 plat_dat->rx_fifo_size = 16384; in sun8i_dwmac_probe()
1226 ret = sun8i_dwmac_set_syscon(&pdev->dev, plat_dat); in sun8i_dwmac_probe()
1230 ret = sun8i_dwmac_init(pdev, plat_dat->bsp_priv); in sun8i_dwmac_probe()
1234 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); in sun8i_dwmac_probe()
1238 ndev = dev_get_drvdata(&pdev->dev); in sun8i_dwmac_probe()
1245 pm_runtime_get_sync(&pdev->dev); in sun8i_dwmac_probe()
1250 if (gmac->variant->soc_has_internal_phy) { in sun8i_dwmac_probe()
1256 dev_err(&pdev->dev, "Failed to register mux\n"); in sun8i_dwmac_probe()
1265 pm_runtime_put(&pdev->dev); in sun8i_dwmac_probe()
1270 reset_control_put(gmac->rst_ephy); in sun8i_dwmac_probe()
1271 clk_put(gmac->ephy_clk); in sun8i_dwmac_probe()
1273 pm_runtime_put_noidle(&pdev->dev); in sun8i_dwmac_probe()
1274 stmmac_dvr_remove(&pdev->dev); in sun8i_dwmac_probe()
1289 struct sunxi_priv_data *gmac = priv->plat->bsp_priv; in sun8i_dwmac_remove()
1291 if (gmac->variant->soc_has_internal_phy) { in sun8i_dwmac_remove()
1292 mdio_mux_uninit(gmac->mux_handle); in sun8i_dwmac_remove()
1294 reset_control_put(gmac->rst_ephy); in sun8i_dwmac_remove()
1295 clk_put(gmac->ephy_clk); in sun8i_dwmac_remove()
1308 struct sunxi_priv_data *gmac = priv->plat->bsp_priv; in sun8i_dwmac_shutdown()
1314 { .compatible = "allwinner,sun8i-h3-emac",
1316 { .compatible = "allwinner,sun8i-v3s-emac",
1318 { .compatible = "allwinner,sun8i-a83t-emac",
1320 { .compatible = "allwinner,sun8i-r40-gmac",
1322 { .compatible = "allwinner,sun50i-a64-emac",
1324 { .compatible = "allwinner,sun50i-h6-emac",
1335 .name = "dwmac-sun8i",