Lines Matching +full:ahb +full:- +full:addr +full:- +full:masks
9 * SPDX-License-Identifier: GPL-2.0+
82 #define ZYNQ_GEM_DMACR_BLENGTH 0x00000004 /* INCR4 AHB bursts */
106 * 0x0008: Auto-negotiation support
110 /* TX BD status masks */
122 u32 nwctrl; /* 0x0 - Network Control reg */
123 u32 nwcfg; /* 0x4 - Network Config reg */
124 u32 nwsr; /* 0x8 - Network Status reg */
126 u32 dmacr; /* 0x10 - DMA Control reg */
127 u32 txsr; /* 0x14 - TX Status reg */
128 u32 rxqbase; /* 0x18 - RX Q Base address reg */
129 u32 txqbase; /* 0x1c - TX Q Base address reg */
130 u32 rxsr; /* 0x20 - RX Status reg */
132 u32 idr; /* 0x2c - Interrupt Disable reg */
134 u32 phymntnc; /* 0x34 - Phy Maintaince reg */
136 u32 hashl; /* 0x80 - Hash Low address reg */
137 u32 hashh; /* 0x84 - Hash High address reg */
140 u32 laddr[4][LADDR_HIGH + 1]; /* 0x8c - Specific1 addr low/high reg */
141 u32 match[4]; /* 0xa8 - Type ID1 Match reg */
144 u32 stat[STAT_SIZE]; /* 0x100 - Octects transmitted Low reg */
148 u32 transmit_q1_ptr; /* 0x440 - Transmit priority queue 1 */
150 u32 receive_q1_ptr; /* 0x480 - Receive priority queue 1 */
155 u32 addr; /* Next descriptor pointer */ member
191 struct zynq_gem_regs *regs = priv->iobase; in phy_setup_op()
194 err = wait_for_bit_le32(®s->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK, in phy_setup_op()
205 writel(mgtcr, ®s->phymntnc); in phy_setup_op()
207 err = wait_for_bit_le32(®s->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK, in phy_setup_op()
213 *data = readl(®s->phymntnc); in phy_setup_op()
247 struct zynq_gem_priv *priv = dev->priv; in phy_detection()
249 if (priv->phyaddr != -1) { in phy_detection()
250 phyread(priv, priv->phyaddr, PHY_DETECT_REG, &phyreg); in phy_detection()
255 priv->phyaddr); in phy_detection()
259 priv->phyaddr); in phy_detection()
260 priv->phyaddr = -1; in phy_detection()
265 if (priv->phyaddr == -1) { in phy_detection()
267 for (i = 31; i >= 0; i--) { in phy_detection()
272 priv->phyaddr = i; in phy_detection()
279 return -1; in phy_detection()
287 struct zynq_gem_regs *regs = priv->iobase; in zynq_gem_setup_mac()
290 macaddrlow = pdata->enetaddr[0]; in zynq_gem_setup_mac()
291 macaddrlow |= pdata->enetaddr[1] << 8; in zynq_gem_setup_mac()
292 macaddrlow |= pdata->enetaddr[2] << 16; in zynq_gem_setup_mac()
293 macaddrlow |= pdata->enetaddr[3] << 24; in zynq_gem_setup_mac()
296 macaddrhigh = pdata->enetaddr[4]; in zynq_gem_setup_mac()
297 macaddrhigh |= pdata->enetaddr[5] << 8; in zynq_gem_setup_mac()
300 writel(0, ®s->laddr[i][LADDR_LOW]); in zynq_gem_setup_mac()
301 writel(0, ®s->laddr[i][LADDR_HIGH]); in zynq_gem_setup_mac()
303 writel(0, ®s->match[i]); in zynq_gem_setup_mac()
306 writel(macaddrlow, ®s->laddr[0][LADDR_LOW]); in zynq_gem_setup_mac()
307 writel(macaddrhigh, ®s->laddr[0][LADDR_HIGH]); in zynq_gem_setup_mac()
316 struct zynq_gem_regs *regs = priv->iobase; in zynq_phy_init()
325 writel(ZYNQ_GEM_NWCTRL_MDEN_MASK, ®s->nwctrl); in zynq_phy_init()
327 if (priv->interface != PHY_INTERFACE_MODE_SGMII) { in zynq_phy_init()
335 priv->phydev = phy_connect(priv->bus, priv->phyaddr, dev, in zynq_phy_init()
336 priv->interface); in zynq_phy_init()
337 if (!priv->phydev) in zynq_phy_init()
338 return -ENODEV; in zynq_phy_init()
340 priv->phydev->supported &= supported | ADVERTISED_Pause | in zynq_phy_init()
342 priv->phydev->advertising = priv->phydev->supported; in zynq_phy_init()
344 if (priv->phy_of_handle > 0) in zynq_phy_init()
345 dev_set_of_offset(priv->phydev->dev, priv->phy_of_handle); in zynq_phy_init()
347 return phy_config(priv->phydev); in zynq_phy_init()
356 struct zynq_gem_regs *regs = priv->iobase; in zynq_gem_init()
357 struct emac_bd *dummy_tx_bd = &priv->tx_bd[TX_FREE_DESC]; in zynq_gem_init()
358 struct emac_bd *dummy_rx_bd = &priv->tx_bd[TX_FREE_DESC + 2]; in zynq_gem_init()
360 if (!priv->init) { in zynq_gem_init()
362 writel(0xFFFFFFFF, ®s->idr); in zynq_gem_init()
365 writel(0, ®s->nwctrl); in zynq_gem_init()
366 writel(0, ®s->txsr); in zynq_gem_init()
367 writel(0, ®s->rxsr); in zynq_gem_init()
368 writel(0, ®s->phymntnc); in zynq_gem_init()
373 writel(0x0, ®s->hashl); in zynq_gem_init()
375 writel(0x0, ®s->hashh); in zynq_gem_init()
379 readl(®s->stat[i]); in zynq_gem_init()
382 memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd)); in zynq_gem_init()
385 priv->rx_bd[i].status = 0xF0000000; in zynq_gem_init()
386 priv->rx_bd[i].addr = in zynq_gem_init()
387 ((ulong)(priv->rxbuffers) + in zynq_gem_init()
391 priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK; in zynq_gem_init()
393 writel((ulong)priv->rx_bd, ®s->rxqbase); in zynq_gem_init()
396 writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); in zynq_gem_init()
399 setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK); in zynq_gem_init()
402 dummy_tx_bd->addr = 0; in zynq_gem_init()
403 dummy_tx_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK | in zynq_gem_init()
407 dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK | in zynq_gem_init()
409 dummy_rx_bd->status = 0; in zynq_gem_init()
411 writel((ulong)dummy_tx_bd, ®s->transmit_q1_ptr); in zynq_gem_init()
412 writel((ulong)dummy_rx_bd, ®s->receive_q1_ptr); in zynq_gem_init()
414 priv->init++; in zynq_gem_init()
417 ret = phy_startup(priv->phydev); in zynq_gem_init()
421 if (!priv->phydev->link) { in zynq_gem_init()
422 printf("%s: No link.\n", priv->phydev->dev->name); in zynq_gem_init()
423 return -1; in zynq_gem_init()
428 if (priv->interface == PHY_INTERFACE_MODE_SGMII) { in zynq_gem_init()
432 writel(readl(®s->pcscntrl) | ZYNQ_GEM_PCS_CTL_ANEG_ENBL, in zynq_gem_init()
433 ®s->pcscntrl); in zynq_gem_init()
437 switch (priv->phydev->speed) { in zynq_gem_init()
440 ®s->nwcfg); in zynq_gem_init()
445 ®s->nwcfg); in zynq_gem_init()
453 ret = clk_set_rate(&priv->clk, clk_rate); in zynq_gem_init()
454 if (IS_ERR_VALUE(ret) && ret != (unsigned long)-ENOSYS) { in zynq_gem_init()
459 ret = clk_enable(&priv->clk); in zynq_gem_init()
460 if (ret && ret != -ENOSYS) { in zynq_gem_init()
465 setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK | in zynq_gem_init()
473 u32 addr, size; in zynq_gem_send() local
475 struct zynq_gem_regs *regs = priv->iobase; in zynq_gem_send()
476 struct emac_bd *current_bd = &priv->tx_bd[1]; in zynq_gem_send()
479 memset(priv->tx_bd, 0, sizeof(struct emac_bd)); in zynq_gem_send()
481 priv->tx_bd->addr = (ulong)ptr; in zynq_gem_send()
482 priv->tx_bd->status = (len & ZYNQ_GEM_TXBUF_FRMLEN_MASK) | in zynq_gem_send()
485 current_bd->addr = 0x0; in zynq_gem_send()
486 current_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK | in zynq_gem_send()
491 writel((ulong)priv->tx_bd, ®s->txqbase); in zynq_gem_send()
493 addr = (ulong) ptr; in zynq_gem_send()
494 addr &= ~(ARCH_DMA_MINALIGN - 1); in zynq_gem_send()
496 flush_dcache_range(addr, addr + size); in zynq_gem_send()
498 addr = (ulong)priv->rxbuffers; in zynq_gem_send()
499 addr &= ~(ARCH_DMA_MINALIGN - 1); in zynq_gem_send()
501 flush_dcache_range(addr, addr + size); in zynq_gem_send()
505 setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK); in zynq_gem_send()
508 if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_EXHAUSTED) in zynq_gem_send()
511 return wait_for_bit_le32(®s->txsr, ZYNQ_GEM_TSR_DONE, in zynq_gem_send()
515 /* Do not check frame_recd flag in rx_status register 0x20 - just poll BD */
519 u32 addr; in zynq_gem_recv() local
521 struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current]; in zynq_gem_recv()
523 if (!(current_bd->addr & ZYNQ_GEM_RXBUF_NEW_MASK)) in zynq_gem_recv()
524 return -1; in zynq_gem_recv()
526 if (!(current_bd->status & in zynq_gem_recv()
529 return -1; in zynq_gem_recv()
532 frame_len = current_bd->status & ZYNQ_GEM_RXBUF_LEN_MASK; in zynq_gem_recv()
535 return -1; in zynq_gem_recv()
538 addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK; in zynq_gem_recv()
539 addr &= ~(ARCH_DMA_MINALIGN - 1); in zynq_gem_recv()
540 *packetp = (uchar *)(uintptr_t)addr; in zynq_gem_recv()
548 struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current]; in zynq_gem_free_pkt()
551 if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK) { in zynq_gem_free_pkt()
552 priv->rx_first_buf = priv->rxbd_current; in zynq_gem_free_pkt()
554 current_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK; in zynq_gem_free_pkt()
555 current_bd->status = 0xF0000000; /* FIXME */ in zynq_gem_free_pkt()
558 if (current_bd->status & ZYNQ_GEM_RXBUF_EOF_MASK) { in zynq_gem_free_pkt()
559 first_bd = &priv->rx_bd[priv->rx_first_buf]; in zynq_gem_free_pkt()
560 first_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK; in zynq_gem_free_pkt()
561 first_bd->status = 0xF0000000; in zynq_gem_free_pkt()
564 if ((++priv->rxbd_current) >= RX_BUF) in zynq_gem_free_pkt()
565 priv->rxbd_current = 0; in zynq_gem_free_pkt()
573 struct zynq_gem_regs *regs = priv->iobase; in zynq_gem_halt()
575 clrsetbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK | in zynq_gem_halt()
581 return -ENOSYS; in zynq_board_read_rom_ethaddr()
589 return -ENOSYS; in zynq_gem_read_rom_mac()
591 return zynq_board_read_rom_ethaddr(pdata->enetaddr); in zynq_gem_read_rom_mac()
594 static int zynq_gem_miiphy_read(struct mii_dev *bus, int addr, in zynq_gem_miiphy_read() argument
597 struct zynq_gem_priv *priv = bus->priv; in zynq_gem_miiphy_read()
601 ret = phyread(priv, addr, reg, &val); in zynq_gem_miiphy_read()
602 debug("%s 0x%x, 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, val, ret); in zynq_gem_miiphy_read()
606 static int zynq_gem_miiphy_write(struct mii_dev *bus, int addr, int devad, in zynq_gem_miiphy_write() argument
609 struct zynq_gem_priv *priv = bus->priv; in zynq_gem_miiphy_write()
611 debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, value); in zynq_gem_miiphy_write()
612 return phywrite(priv, addr, reg, value); in zynq_gem_miiphy_write()
622 priv->rxbuffers = memalign(ARCH_DMA_MINALIGN, RX_BUF * PKTSIZE_ALIGN); in zynq_gem_probe()
623 memset(priv->rxbuffers, 0, RX_BUF * PKTSIZE_ALIGN); in zynq_gem_probe()
631 priv->tx_bd = (struct emac_bd *)bd_space; in zynq_gem_probe()
632 priv->rx_bd = (struct emac_bd *)((ulong)bd_space + BD_SEPRN_SPACE); in zynq_gem_probe()
634 ret = clk_get_by_name(dev, "tx_clk", &priv->clk); in zynq_gem_probe()
637 return -EINVAL; in zynq_gem_probe()
640 priv->bus = mdio_alloc(); in zynq_gem_probe()
641 priv->bus->read = zynq_gem_miiphy_read; in zynq_gem_probe()
642 priv->bus->write = zynq_gem_miiphy_write; in zynq_gem_probe()
643 priv->bus->priv = priv; in zynq_gem_probe()
645 ret = mdio_register_seq(priv->bus, dev->seq); in zynq_gem_probe()
656 free(priv->phydev); in zynq_gem_remove()
657 mdio_unregister(priv->bus); in zynq_gem_remove()
658 mdio_free(priv->bus); in zynq_gem_remove()
680 pdata->iobase = (phys_addr_t)devfdt_get_addr(dev); in zynq_gem_ofdata_to_platdata()
681 priv->iobase = (struct zynq_gem_regs *)pdata->iobase; in zynq_gem_ofdata_to_platdata()
683 priv->phyaddr = -1; in zynq_gem_ofdata_to_platdata()
685 priv->phy_of_handle = fdtdec_lookup_phandle(gd->fdt_blob, node, in zynq_gem_ofdata_to_platdata()
686 "phy-handle"); in zynq_gem_ofdata_to_platdata()
687 if (priv->phy_of_handle > 0) in zynq_gem_ofdata_to_platdata()
688 priv->phyaddr = fdtdec_get_int(gd->fdt_blob, in zynq_gem_ofdata_to_platdata()
689 priv->phy_of_handle, "reg", -1); in zynq_gem_ofdata_to_platdata()
691 phy_mode = fdt_getprop(gd->fdt_blob, node, "phy-mode", NULL); in zynq_gem_ofdata_to_platdata()
693 pdata->phy_interface = phy_get_interface_by_name(phy_mode); in zynq_gem_ofdata_to_platdata()
694 if (pdata->phy_interface == -1) { in zynq_gem_ofdata_to_platdata()
696 return -EINVAL; in zynq_gem_ofdata_to_platdata()
698 priv->interface = pdata->phy_interface; in zynq_gem_ofdata_to_platdata()
700 printf("ZYNQ GEM: %lx, phyaddr %x, interface %s\n", (ulong)priv->iobase, in zynq_gem_ofdata_to_platdata()
701 priv->phyaddr, phy_string_for_interface(priv->interface)); in zynq_gem_ofdata_to_platdata()
707 { .compatible = "cdns,zynqmp-gem" },
708 { .compatible = "cdns,zynq-gem" },