Lines Matching +full:ar9331 +full:- +full:switch
1 // SPDX-License-Identifier: GPL-2.0+
74 /* ETH Configuration 0 - 5 */
152 * Switch and MDIO access
156 struct ar7xxx_eth_priv *priv = bus->priv; in ag7xxx_switch_read()
157 void __iomem *regs = priv->phyregs; in ag7xxx_switch_read()
179 struct ar7xxx_eth_priv *priv = bus->priv; in ag7xxx_switch_write()
180 void __iomem *regs = priv->phyregs; in ag7xxx_switch_write()
195 struct ar7xxx_eth_priv *priv = bus->priv; in ag7xxx_switch_reg_read()
203 if (priv->model == AG7XXX_MODEL_AG933X) { in ag7xxx_switch_reg_read()
206 } else if (priv->model == AG7XXX_MODEL_AG934X) { in ag7xxx_switch_reg_read()
210 return -EINVAL; in ag7xxx_switch_reg_read()
235 struct ar7xxx_eth_priv *priv = bus->priv; in ag7xxx_switch_reg_write()
242 if (priv->model == AG7XXX_MODEL_AG933X) { in ag7xxx_switch_reg_write()
245 } else if (priv->model == AG7XXX_MODEL_AG934X) { in ag7xxx_switch_reg_write()
249 return -EINVAL; in ag7xxx_switch_reg_write()
259 * The switch on AR933x has some special register behavior, which in ag7xxx_switch_reg_write()
266 if ((priv->model == AG7XXX_MODEL_AG933X) && (reg == 0x98)) { in ag7xxx_switch_reg_write()
313 return -ETIMEDOUT; in ag7xxx_mdio_rw()
346 curr = &priv->tx_mac_descrtable[i]; in ag7xxx_dma_clean_tx()
347 next = &priv->tx_mac_descrtable[(i + 1) % CONFIG_TX_DESCR_NUM]; in ag7xxx_dma_clean_tx()
349 curr->data_addr = virt_to_phys(&priv->txbuffs[i * CONFIG_ETH_BUFSIZE]); in ag7xxx_dma_clean_tx()
350 curr->config = AG7XXX_DMADESC_IS_EMPTY; in ag7xxx_dma_clean_tx()
351 curr->next_desc = virt_to_phys(next); in ag7xxx_dma_clean_tx()
354 priv->tx_currdescnum = 0; in ag7xxx_dma_clean_tx()
357 start = (u32)(&priv->tx_mac_descrtable[0]); in ag7xxx_dma_clean_tx()
358 end = start + sizeof(priv->tx_mac_descrtable); in ag7xxx_dma_clean_tx()
370 curr = &priv->rx_mac_descrtable[i]; in ag7xxx_dma_clean_rx()
371 next = &priv->rx_mac_descrtable[(i + 1) % CONFIG_RX_DESCR_NUM]; in ag7xxx_dma_clean_rx()
373 curr->data_addr = virt_to_phys(&priv->rxbuffs[i * CONFIG_ETH_BUFSIZE]); in ag7xxx_dma_clean_rx()
374 curr->config = AG7XXX_DMADESC_IS_EMPTY; in ag7xxx_dma_clean_rx()
375 curr->next_desc = virt_to_phys(next); in ag7xxx_dma_clean_rx()
378 priv->rx_currdescnum = 0; in ag7xxx_dma_clean_rx()
381 start = (u32)(&priv->rx_mac_descrtable[0]); in ag7xxx_dma_clean_rx()
382 end = start + sizeof(priv->rx_mac_descrtable); in ag7xxx_dma_clean_rx()
386 start = (u32)&priv->rxbuffs; in ag7xxx_dma_clean_rx()
387 end = start + sizeof(priv->rxbuffs); in ag7xxx_dma_clean_rx()
400 curr = &priv->tx_mac_descrtable[priv->tx_currdescnum]; in ag7xxx_eth_send()
407 if (!(curr->config & AG7XXX_DMADESC_IS_EMPTY)) { in ag7xxx_eth_send()
409 return -EPERM; in ag7xxx_eth_send()
413 memcpy(phys_to_virt(curr->data_addr), packet, length); in ag7xxx_eth_send()
414 curr->config = length & AG7XXX_DMADESC_PKT_SIZE_MASK; in ag7xxx_eth_send()
420 start = (u32)phys_to_virt(curr->data_addr); in ag7xxx_eth_send()
426 priv->regs + AG7XXX_ETH_DMA_TX_CTRL); in ag7xxx_eth_send()
428 /* Switch to next TX descriptor. */ in ag7xxx_eth_send()
429 priv->tx_currdescnum = (priv->tx_currdescnum + 1) % CONFIG_TX_DESCR_NUM; in ag7xxx_eth_send()
440 curr = &priv->rx_mac_descrtable[priv->rx_currdescnum]; in ag7xxx_eth_recv()
448 if (curr->config & AG7XXX_DMADESC_IS_EMPTY) in ag7xxx_eth_recv()
449 return -EAGAIN; in ag7xxx_eth_recv()
451 length = curr->config & AG7XXX_DMADESC_PKT_SIZE_MASK; in ag7xxx_eth_recv()
454 start = (u32)phys_to_virt(curr->data_addr); in ag7xxx_eth_recv()
459 *packetp = phys_to_virt(curr->data_addr); in ag7xxx_eth_recv()
470 curr = &priv->rx_mac_descrtable[priv->rx_currdescnum]; in ag7xxx_eth_free_pkt()
472 curr->config = AG7XXX_DMADESC_IS_EMPTY; in ag7xxx_eth_free_pkt()
479 /* Switch to next RX descriptor. */ in ag7xxx_eth_free_pkt()
480 priv->rx_currdescnum = (priv->rx_currdescnum + 1) % CONFIG_RX_DESCR_NUM; in ag7xxx_eth_free_pkt()
496 writel(virt_to_phys(&priv->tx_mac_descrtable[priv->tx_currdescnum]), in ag7xxx_eth_start()
497 priv->regs + AG7XXX_ETH_DMA_TX_DESC); in ag7xxx_eth_start()
498 writel(virt_to_phys(&priv->rx_mac_descrtable[priv->rx_currdescnum]), in ag7xxx_eth_start()
499 priv->regs + AG7XXX_ETH_DMA_RX_DESC); in ag7xxx_eth_start()
501 priv->regs + AG7XXX_ETH_DMA_RX_CTRL); in ag7xxx_eth_start()
511 writel(0, priv->regs + AG7XXX_ETH_DMA_TX_CTRL); in ag7xxx_eth_stop()
512 wait_for_bit_le32(priv->regs + AG7XXX_ETH_DMA_TX_CTRL, ~0, 0, in ag7xxx_eth_stop()
516 writel(0, priv->regs + AG7XXX_ETH_DMA_RX_CTRL); in ag7xxx_eth_stop()
517 wait_for_bit_le32(priv->regs + AG7XXX_ETH_DMA_RX_CTRL, ~0, 0, in ag7xxx_eth_stop()
528 unsigned char *mac = pdata->enetaddr; in ag7xxx_eth_write_hwaddr()
534 writel(macid_lo, priv->regs + AG7XXX_ETH_ADDR1); in ag7xxx_eth_write_hwaddr()
535 writel(macid_hi, priv->regs + AG7XXX_ETH_ADDR2); in ag7xxx_eth_write_hwaddr()
545 setbits_be32(priv->regs + AG7XXX_ETH_CFG1, in ag7xxx_hw_setup()
552 priv->regs + AG7XXX_ETH_CFG1); in ag7xxx_hw_setup()
554 if (priv->interface == PHY_INTERFACE_MODE_RMII) in ag7xxx_hw_setup()
559 clrsetbits_be32(priv->regs + AG7XXX_ETH_CFG2, in ag7xxx_hw_setup()
564 writel(0xfff0000, priv->regs + AG7XXX_ETH_FIFO_CFG_1); in ag7xxx_hw_setup()
565 writel(0x1fff, priv->regs + AG7XXX_ETH_FIFO_CFG_2); in ag7xxx_hw_setup()
567 writel(0x1f00, priv->regs + AG7XXX_ETH_FIFO_CFG_0); in ag7xxx_hw_setup()
568 setbits_be32(priv->regs + AG7XXX_ETH_FIFO_CFG_4, 0x3ffff); in ag7xxx_hw_setup()
569 writel(0x10ffff, priv->regs + AG7XXX_ETH_FIFO_CFG_1); in ag7xxx_hw_setup()
570 writel(0xaaa0555, priv->regs + AG7XXX_ETH_FIFO_CFG_2); in ag7xxx_hw_setup()
571 writel(0x7eccf, priv->regs + AG7XXX_ETH_FIFO_CFG_5); in ag7xxx_hw_setup()
572 writel(0x1f00140, priv->regs + AG7XXX_ETH_FIFO_CFG_3); in ag7xxx_hw_setup()
579 switch (freq / 1000000) { in ag7xxx_mii_get_div()
595 if (priv->model == AG7XXX_MODEL_AG933X) { in ag7xxx_mii_setup()
596 /* Unit 0 is PHY-less on AR9331, see datasheet Figure 2-3 */ in ag7xxx_mii_setup()
597 if (priv->interface == PHY_INTERFACE_MODE_RMII) in ag7xxx_mii_setup()
601 if (priv->model == AG7XXX_MODEL_AG934X) { in ag7xxx_mii_setup()
603 priv->regs + AG7XXX_ETH_MII_MGMT_CFG); in ag7xxx_mii_setup()
604 writel(0x4, priv->regs + AG7XXX_ETH_MII_MGMT_CFG); in ag7xxx_mii_setup()
610 priv->regs + AG7XXX_ETH_MII_MGMT_CFG); in ag7xxx_mii_setup()
611 writel(div, priv->regs + AG7XXX_ETH_MII_MGMT_CFG); in ag7xxx_mii_setup()
613 /* Check the switch */ in ag7xxx_mii_setup()
614 ret = ag7xxx_switch_reg_read(priv->bus, 0x10c, ®); in ag7xxx_mii_setup()
624 return -EINVAL; in ag7xxx_mii_setup()
631 /* Configure switch port 4 (GMAC0) */ in ag933x_phy_setup_wan()
632 return ag7xxx_mdio_write(priv->bus, 4, 0, MII_BMCR, 0x9000); in ag933x_phy_setup_wan()
641 /* Reset the switch */ in ag933x_phy_setup_lan()
642 ret = ag7xxx_switch_reg_read(priv->bus, 0, ®); in ag933x_phy_setup_lan()
646 ret = ag7xxx_switch_reg_write(priv->bus, 0, reg); in ag933x_phy_setup_lan()
651 ret = ag7xxx_switch_reg_read(priv->bus, 0, ®); in ag933x_phy_setup_lan()
656 /* Configure switch ports 0...3 (GMAC1) */ in ag933x_phy_setup_lan()
658 ret = ag7xxx_mdio_write(priv->bus, 0x4, 0, MII_BMCR, 0x9000); in ag933x_phy_setup_lan()
664 ret = ag7xxx_switch_reg_write(priv->bus, 0x78, BIT(8)); in ag933x_phy_setup_lan()
669 ret = ag7xxx_switch_reg_write(priv->bus, i * 0x100, BIT(9)); in ag933x_phy_setup_lan()
675 ret = ag7xxx_switch_reg_write(priv->bus, 0x38, 0xc000050e); in ag933x_phy_setup_lan()
680 ret = ag7xxx_switch_reg_write(priv->bus, 0x104, 0x4004); in ag933x_phy_setup_lan()
685 ret = ag7xxx_switch_reg_write(priv->bus, 0x70, 0xfa50); in ag933x_phy_setup_lan()
690 ret = ag7xxx_switch_reg_read(priv->bus, 0x5c, ®); in ag933x_phy_setup_lan()
694 ret = ag7xxx_switch_reg_write(priv->bus, 0x5c, reg); in ag933x_phy_setup_lan()
706 ret = ag7xxx_mdio_write(priv->bus, port, 0, MII_ADVERTISE, in ag933x_phy_setup_reset_set()
712 if (priv->model == AG7XXX_MODEL_AG934X) { in ag933x_phy_setup_reset_set()
713 ret = ag7xxx_mdio_write(priv->bus, port, 0, MII_CTRL1000, in ag933x_phy_setup_reset_set()
719 return ag7xxx_mdio_write(priv->bus, port, 0, MII_BMCR, in ag933x_phy_setup_reset_set()
729 ret = ag7xxx_mdio_read(priv->bus, port, 0, MII_BMCR); in ag933x_phy_setup_reset_fin()
743 if (priv->model == AG7XXX_MODEL_AG933X) in ag933x_phy_setup_common()
745 else if (priv->model == AG7XXX_MODEL_AG934X) in ag933x_phy_setup_common()
748 return -EINVAL; in ag933x_phy_setup_common()
750 if (priv->interface == PHY_INTERFACE_MODE_RMII) { in ag933x_phy_setup_common()
760 ret = ag7xxx_mdio_read(priv->bus, phymax, 0, MII_MIPSCR); in ag933x_phy_setup_common()
767 /* Switch ports */ in ag933x_phy_setup_common()
782 ret = ag7xxx_mdio_read(priv->bus, i, 0, MII_MIPSCR); in ag933x_phy_setup_common()
796 ret = ag7xxx_switch_reg_write(priv->bus, 0x624, 0x7f7f7f7f); in ag934x_phy_setup()
799 ret = ag7xxx_switch_reg_write(priv->bus, 0x10, 0x40000000); in ag934x_phy_setup()
802 ret = ag7xxx_switch_reg_write(priv->bus, 0x4, 0x07600000); in ag934x_phy_setup()
805 ret = ag7xxx_switch_reg_write(priv->bus, 0xc, 0x01000000); in ag934x_phy_setup()
808 ret = ag7xxx_switch_reg_write(priv->bus, 0x7c, 0x0000007e); in ag934x_phy_setup()
813 ret = ag7xxx_switch_reg_read(priv->bus, 0, ®); in ag934x_phy_setup()
818 ret = ag7xxx_mdio_write(priv->bus, i, 0, 0x1d, 0x0); in ag934x_phy_setup()
821 ret = ag7xxx_mdio_write(priv->bus, i, 0, 0x1e, 0x02ea); in ag934x_phy_setup()
824 ret = ag7xxx_mdio_write(priv->bus, i, 0, 0x1d, 0x3d); in ag934x_phy_setup()
827 ret = ag7xxx_mdio_write(priv->bus, i, 0, 0x1e, 0x68a0); in ag934x_phy_setup()
833 ret = ag7xxx_switch_reg_read(priv->bus, 0x66c, ®); in ag934x_phy_setup()
837 ret = ag7xxx_switch_reg_write(priv->bus, 0x66c, reg); in ag934x_phy_setup()
856 if (priv->model == AG7XXX_MODEL_AG933X) { in ag7xxx_mac_probe()
857 if (priv->interface == PHY_INTERFACE_MODE_RMII) in ag7xxx_mac_probe()
861 } else if (priv->model == AG7XXX_MODEL_AG934X) { in ag7xxx_mac_probe()
864 return -EINVAL; in ag7xxx_mac_probe()
879 return -ENOMEM; in ag7xxx_mdio_probe()
881 bus->read = ag7xxx_mdio_read; in ag7xxx_mdio_probe()
882 bus->write = ag7xxx_mdio_write; in ag7xxx_mdio_probe()
883 snprintf(bus->name, sizeof(bus->name), dev->name); in ag7xxx_mdio_probe()
885 bus->priv = (void *)priv; in ag7xxx_mdio_probe()
894 offset = fdtdec_lookup_phandle(gd->fdt_blob, dev_of_offset(dev), "phy"); in ag7xxx_get_phy_iface_offset()
897 return -EINVAL; in ag7xxx_get_phy_iface_offset()
900 offset = fdt_parent_offset(gd->fdt_blob, offset); in ag7xxx_get_phy_iface_offset()
904 return -EINVAL; in ag7xxx_get_phy_iface_offset()
907 offset = fdt_parent_offset(gd->fdt_blob, offset); in ag7xxx_get_phy_iface_offset()
911 return -EINVAL; in ag7xxx_get_phy_iface_offset()
928 phyreg = fdtdec_get_int(gd->fdt_blob, ret, "reg", -1); in ag7xxx_eth_probe()
930 iobase = map_physmem(pdata->iobase, 0x200, MAP_NOCACHE); in ag7xxx_eth_probe()
935 priv->regs = iobase; in ag7xxx_eth_probe()
936 priv->phyregs = phyiobase; in ag7xxx_eth_probe()
937 priv->interface = pdata->phy_interface; in ag7xxx_eth_probe()
938 priv->model = dev_get_driver_data(dev); in ag7xxx_eth_probe()
944 priv->bus = miiphy_get_dev_by_name(dev->name); in ag7xxx_eth_probe()
956 free(priv->phydev); in ag7xxx_eth_remove()
957 mdio_unregister(priv->bus); in ag7xxx_eth_remove()
958 mdio_free(priv->bus); in ag7xxx_eth_remove()
978 pdata->iobase = devfdt_get_addr(dev); in ag7xxx_eth_ofdata_to_platdata()
979 pdata->phy_interface = -1; in ag7xxx_eth_ofdata_to_platdata()
986 phy_mode = fdt_getprop(gd->fdt_blob, ret, "phy-mode", NULL); in ag7xxx_eth_ofdata_to_platdata()
988 pdata->phy_interface = phy_get_interface_by_name(phy_mode); in ag7xxx_eth_ofdata_to_platdata()
989 if (pdata->phy_interface == -1) { in ag7xxx_eth_ofdata_to_platdata()
991 return -EINVAL; in ag7xxx_eth_ofdata_to_platdata()
998 { .compatible = "qca,ag933x-mac", .data = AG7XXX_MODEL_AG933X },
999 { .compatible = "qca,ag934x-mac", .data = AG7XXX_MODEL_AG934X },