Lines Matching +full:stm32 +full:- +full:dwmac
5 * SPDX-License-Identifier: GPL-2.0+
9 * Designware ethernet IP driver for U-Boot
29 struct dw_eth_dev *priv = dev_get_priv((struct udevice *)bus->priv); in dw_mdio_read()
30 struct eth_mac_regs *mac_p = priv->mac_regs_p; in dw_mdio_read()
32 struct eth_mac_regs *mac_p = bus->priv; in dw_mdio_read()
41 writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr); in dw_mdio_read()
45 if (!(readl(&mac_p->miiaddr) & MII_BUSY)) in dw_mdio_read()
46 return readl(&mac_p->miidata); in dw_mdio_read()
50 return -ETIMEDOUT; in dw_mdio_read()
57 struct dw_eth_dev *priv = dev_get_priv((struct udevice *)bus->priv); in dw_mdio_write()
58 struct eth_mac_regs *mac_p = priv->mac_regs_p; in dw_mdio_write()
60 struct eth_mac_regs *mac_p = bus->priv; in dw_mdio_write()
64 int ret = -ETIMEDOUT, timeout = CONFIG_MDIO_TIMEOUT; in dw_mdio_write()
66 writel(val, &mac_p->miidata); in dw_mdio_write()
70 writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr); in dw_mdio_write()
74 if (!(readl(&mac_p->miiaddr) & MII_BUSY)) { in dw_mdio_write()
87 struct udevice *dev = bus->priv; in dw_mdio_reset()
92 if (!dm_gpio_is_valid(&priv->reset_gpio)) in dw_mdio_reset()
96 ret = dm_gpio_set_value(&priv->reset_gpio, 0); in dw_mdio_reset()
100 udelay(pdata->reset_delays[0]); in dw_mdio_reset()
102 ret = dm_gpio_set_value(&priv->reset_gpio, 1); in dw_mdio_reset()
106 udelay(pdata->reset_delays[1]); in dw_mdio_reset()
108 ret = dm_gpio_set_value(&priv->reset_gpio, 0); in dw_mdio_reset()
112 udelay(pdata->reset_delays[2]); in dw_mdio_reset()
124 return -ENOMEM; in dw_mdio_init()
127 bus->read = dw_mdio_read; in dw_mdio_init()
128 bus->write = dw_mdio_write; in dw_mdio_init()
129 snprintf(bus->name, sizeof(bus->name), "%s", name); in dw_mdio_init()
131 bus->reset = dw_mdio_reset; in dw_mdio_init()
134 bus->priv = priv; in dw_mdio_init()
141 struct eth_dma_regs *dma_p = priv->dma_regs_p; in tx_descs_init()
142 struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable[0]; in tx_descs_init()
143 char *txbuffs = &priv->txbuffs[0]; in tx_descs_init()
149 desc_p->dmamac_addr = (ulong)&txbuffs[idx * CONFIG_ETH_BUFSIZE]; in tx_descs_init()
150 desc_p->dmamac_next = (ulong)&desc_table_p[idx + 1]; in tx_descs_init()
153 desc_p->txrx_status &= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST | in tx_descs_init()
158 desc_p->txrx_status |= DESC_TXSTS_TXCHAIN; in tx_descs_init()
159 desc_p->dmamac_cntl = 0; in tx_descs_init()
160 desc_p->txrx_status &= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA); in tx_descs_init()
162 desc_p->dmamac_cntl = DESC_TXCTRL_TXCHAIN; in tx_descs_init()
163 desc_p->txrx_status = 0; in tx_descs_init()
168 desc_p->dmamac_next = (ulong)&desc_table_p[0]; in tx_descs_init()
171 flush_dcache_range((ulong)priv->tx_mac_descrtable, in tx_descs_init()
172 (ulong)priv->tx_mac_descrtable + in tx_descs_init()
173 sizeof(priv->tx_mac_descrtable)); in tx_descs_init()
175 writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr); in tx_descs_init()
176 priv->tx_currdescnum = 0; in tx_descs_init()
181 struct eth_dma_regs *dma_p = priv->dma_regs_p; in rx_descs_init()
182 struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable[0]; in rx_descs_init()
183 char *rxbuffs = &priv->rxbuffs[0]; in rx_descs_init()
197 desc_p->dmamac_addr = (ulong)&rxbuffs[idx * CONFIG_ETH_BUFSIZE]; in rx_descs_init()
198 desc_p->dmamac_next = (ulong)&desc_table_p[idx + 1]; in rx_descs_init()
200 desc_p->dmamac_cntl = in rx_descs_init()
204 desc_p->txrx_status = DESC_RXSTS_OWNBYDMA; in rx_descs_init()
208 desc_p->dmamac_next = (ulong)&desc_table_p[0]; in rx_descs_init()
211 flush_dcache_range((ulong)priv->rx_mac_descrtable, in rx_descs_init()
212 (ulong)priv->rx_mac_descrtable + in rx_descs_init()
213 sizeof(priv->rx_mac_descrtable)); in rx_descs_init()
215 writel((ulong)&desc_table_p[0], &dma_p->rxdesclistaddr); in rx_descs_init()
216 priv->rx_currdescnum = 0; in rx_descs_init()
221 struct eth_mac_regs *mac_p = priv->mac_regs_p; in _dw_write_hwaddr()
228 writel(macid_hi, &mac_p->macaddr0hi); in _dw_write_hwaddr()
229 writel(macid_lo, &mac_p->macaddr0lo); in _dw_write_hwaddr()
237 u32 conf = readl(&mac_p->conf) | FRAMEBURSTENABLE | DISABLERXOWN; in dw_adjust_link()
239 if (!phydev->link) { in dw_adjust_link()
240 printf("%s: No link.\n", phydev->dev->name); in dw_adjust_link()
244 if (phydev->speed != 1000) in dw_adjust_link()
249 if (phydev->speed == 100) in dw_adjust_link()
252 if (phydev->duplex) in dw_adjust_link()
255 writel(conf, &mac_p->conf); in dw_adjust_link()
257 printf("Speed: %d, %s duplex%s\n", phydev->speed, in dw_adjust_link()
258 (phydev->duplex) ? "full" : "half", in dw_adjust_link()
259 (phydev->port == PORT_FIBRE) ? ", fiber mode" : ""); in dw_adjust_link()
266 struct eth_mac_regs *mac_p = priv->mac_regs_p; in _dw_eth_halt()
267 struct eth_dma_regs *dma_p = priv->dma_regs_p; in _dw_eth_halt()
269 writel(readl(&mac_p->conf) & ~(RXENABLE | TXENABLE), &mac_p->conf); in _dw_eth_halt()
270 writel(readl(&dma_p->opmode) & ~(RXSTART | TXSTART), &dma_p->opmode); in _dw_eth_halt()
272 phy_shutdown(priv->phydev); in _dw_eth_halt()
277 struct eth_mac_regs *mac_p = priv->mac_regs_p; in designware_eth_init()
278 struct eth_dma_regs *dma_p = priv->dma_regs_p; in designware_eth_init()
282 writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode); in designware_eth_init()
285 while (readl(&dma_p->busmode) & DMAMAC_SRST) { in designware_eth_init()
288 return -ETIMEDOUT; in designware_eth_init()
303 writel(FIXEDBURST | PRIORXTX_41 | DMA_PBL, &dma_p->busmode); in designware_eth_init()
306 writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD, in designware_eth_init()
307 &dma_p->opmode); in designware_eth_init()
309 writel(readl(&dma_p->opmode) | FLUSHTXFIFO, in designware_eth_init()
310 &dma_p->opmode); in designware_eth_init()
313 writel(readl(&dma_p->opmode) | RXSTART | TXSTART, &dma_p->opmode); in designware_eth_init()
316 writel((CONFIG_DW_AXI_BURST_LEN & 0x1FF >> 1), &dma_p->axibus); in designware_eth_init()
320 ret = phy_startup(priv->phydev); in designware_eth_init()
323 priv->phydev->dev->name); in designware_eth_init()
327 ret = dw_adjust_link(priv, mac_p, priv->phydev); in designware_eth_init()
336 struct eth_mac_regs *mac_p = priv->mac_regs_p; in designware_eth_enable()
338 if (!priv->phydev->link) in designware_eth_enable()
339 return -EIO; in designware_eth_enable()
341 writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf); in designware_eth_enable()
348 struct eth_dma_regs *dma_p = priv->dma_regs_p; in _dw_eth_send()
349 u32 desc_num = priv->tx_currdescnum; in _dw_eth_send()
350 struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num]; in _dw_eth_send()
354 ulong data_start = desc_p->dmamac_addr; in _dw_eth_send()
367 if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) { in _dw_eth_send()
369 return -EPERM; in _dw_eth_send()
378 desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST; in _dw_eth_send()
379 desc_p->dmamac_cntl |= (length << DESC_TXCTRL_SIZE1SHFT) & in _dw_eth_send()
382 desc_p->txrx_status &= ~(DESC_TXSTS_MSK); in _dw_eth_send()
383 desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA; in _dw_eth_send()
385 desc_p->dmamac_cntl |= ((length << DESC_TXCTRL_SIZE1SHFT) & in _dw_eth_send()
389 desc_p->txrx_status = DESC_TXSTS_OWNBYDMA; in _dw_eth_send()
395 /* Test the wrap-around condition. */ in _dw_eth_send()
399 priv->tx_currdescnum = desc_num; in _dw_eth_send()
402 writel(POLL_DATA, &dma_p->txpolldemand); in _dw_eth_send()
409 u32 status, desc_num = priv->rx_currdescnum; in _dw_eth_recv()
410 struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num]; in _dw_eth_recv()
411 int length = -EAGAIN; in _dw_eth_recv()
415 ulong data_start = desc_p->dmamac_addr; in _dw_eth_recv()
421 status = desc_p->txrx_status; in _dw_eth_recv()
432 *packetp = (uchar *)(ulong)desc_p->dmamac_addr; in _dw_eth_recv()
440 u32 desc_num = priv->rx_currdescnum; in _dw_free_pkt()
441 struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num]; in _dw_free_pkt()
450 desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA; in _dw_free_pkt()
452 /* Flush only status field - others weren't changed */ in _dw_free_pkt()
455 /* Test the wrap-around condition. */ in _dw_free_pkt()
458 priv->rx_currdescnum = desc_num; in _dw_free_pkt()
472 phydev = phy_find_by_mask(priv->bus, mask, priv->interface); in dw_phy_init()
474 return -ENODEV; in dw_phy_init()
478 phydev->supported &= PHY_GBIT_FEATURES; in dw_phy_init()
479 if (priv->max_speed) { in dw_phy_init()
480 ret = phy_set_supported(phydev, priv->max_speed); in dw_phy_init()
484 phydev->advertising = phydev->supported; in dw_phy_init()
486 priv->phydev = phydev; in dw_phy_init()
497 ret = designware_eth_init(dev->priv, dev->enetaddr); in dw_eth_init()
499 ret = designware_eth_enable(dev->priv); in dw_eth_init()
506 return _dw_eth_send(dev->priv, packet, length); in dw_eth_send()
514 length = _dw_eth_recv(dev->priv, &packet); in dw_eth_recv()
515 if (length == -EAGAIN) in dw_eth_recv()
519 _dw_free_pkt(dev->priv); in dw_eth_recv()
526 return _dw_eth_halt(dev->priv); in dw_eth_halt()
531 return _dw_write_hwaddr(dev->priv, dev->enetaddr); in dw_write_hwaddr()
541 return -ENOMEM; in designware_initialize()
551 return -ENOMEM; in designware_initialize()
556 return -EINVAL; in designware_initialize()
562 sprintf(dev->name, "dwmac.%lx", base_addr); in designware_initialize()
563 dev->iobase = (int)base_addr; in designware_initialize()
564 dev->priv = priv; in designware_initialize()
566 priv->dev = dev; in designware_initialize()
567 priv->mac_regs_p = (struct eth_mac_regs *)base_addr; in designware_initialize()
568 priv->dma_regs_p = (struct eth_dma_regs *)(base_addr + in designware_initialize()
571 dev->init = dw_eth_init; in designware_initialize()
572 dev->send = dw_eth_send; in designware_initialize()
573 dev->recv = dw_eth_recv; in designware_initialize()
574 dev->halt = dw_eth_halt; in designware_initialize()
575 dev->write_hwaddr = dw_write_hwaddr; in designware_initialize()
579 priv->interface = interface; in designware_initialize()
581 dw_mdio_init(dev->name, priv->mac_regs_p); in designware_initialize()
582 priv->bus = miiphy_get_dev_by_name(dev->name); in designware_initialize()
595 ret = designware_eth_init(priv, pdata->enetaddr); in designware_eth_start()
638 return _dw_write_hwaddr(priv, pdata->enetaddr); in designware_eth_write_hwaddr()
661 u32 iobase = pdata->iobase; in designware_eth_probe()
668 ret = device_get_supply_regulator(dev, "phy-supply", in designware_eth_probe()
671 debug("%s: No phy supply\n", dev->name); in designware_eth_probe()
691 pdata->iobase = iobase; in designware_eth_probe()
692 pdata->phy_interface = PHY_INTERFACE_MODE_RMII; in designware_eth_probe()
698 priv->mac_regs_p = (struct eth_mac_regs *)ioaddr; in designware_eth_probe()
699 priv->dma_regs_p = (struct eth_dma_regs *)(ioaddr + DW_DMA_BASE_OFFSET); in designware_eth_probe()
700 priv->interface = pdata->phy_interface; in designware_eth_probe()
701 priv->max_speed = pdata->max_speed; in designware_eth_probe()
703 dw_mdio_init(dev->name, dev); in designware_eth_probe()
704 priv->bus = miiphy_get_dev_by_name(dev->name); in designware_eth_probe()
716 free(priv->phydev); in designware_eth_remove()
717 mdio_unregister(priv->bus); in designware_eth_remove()
718 mdio_free(priv->bus); in designware_eth_remove()
738 struct eth_pdata *pdata = &dw_pdata->eth_pdata; in designware_eth_ofdata_to_platdata()
745 pdata->iobase = dev_read_addr(dev); in designware_eth_ofdata_to_platdata()
746 pdata->phy_interface = -1; in designware_eth_ofdata_to_platdata()
747 phy_mode = dev_read_string(dev, "phy-mode"); in designware_eth_ofdata_to_platdata()
749 pdata->phy_interface = phy_get_interface_by_name(phy_mode); in designware_eth_ofdata_to_platdata()
750 if (pdata->phy_interface == -1) { in designware_eth_ofdata_to_platdata()
752 return -EINVAL; in designware_eth_ofdata_to_platdata()
755 pdata->max_speed = dev_read_u32_default(dev, "max-speed", 0); in designware_eth_ofdata_to_platdata()
758 if (dev_read_bool(dev, "snps,reset-active-low")) in designware_eth_ofdata_to_platdata()
761 ret = gpio_request_by_name(dev, "snps,reset-gpio", 0, in designware_eth_ofdata_to_platdata()
762 &priv->reset_gpio, reset_flags); in designware_eth_ofdata_to_platdata()
764 ret = dev_read_u32_array(dev, "snps,reset-delays-us", in designware_eth_ofdata_to_platdata()
765 dw_pdata->reset_delays, 3); in designware_eth_ofdata_to_platdata()
766 } else if (ret == -ENOENT) { in designware_eth_ofdata_to_platdata()
775 { .compatible = "allwinner,sun7i-a20-gmac" },
776 { .compatible = "altr,socfpga-stmmac" },
777 { .compatible = "amlogic,meson6-dwmac" },
778 { .compatible = "amlogic,meson-gx-dwmac" },
779 { .compatible = "st,stm32-dwmac" },