Merge git://git.denx.de/u-boot-mips
[oweals/u-boot.git] / drivers / net / zynq_gem.c
index 36397fe053835c42d87974b6b1fc94a7bb4d5716..2cc49bca922a1f0896a9e6368813df77313b0661 100644 (file)
@@ -181,9 +181,8 @@ struct zynq_gem_priv {
        struct phy_device *phydev;
        int phy_of_handle;
        struct mii_dev *bus;
-#if defined(CONFIG_CLK) || defined(CONFIG_SPL_CLK)
        struct clk clk;
-#endif
+       bool int_pcs;
 };
 
 static u32 phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum,
@@ -193,8 +192,8 @@ static u32 phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum,
        struct zynq_gem_regs *regs = priv->iobase;
        int err;
 
-       err = wait_for_bit(__func__, &regs->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
-                           true, 20000, true);
+       err = wait_for_bit_le32(&regs->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
+                               true, 20000, false);
        if (err)
                return err;
 
@@ -206,8 +205,8 @@ static u32 phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum,
        /* Write mgtcr and wait for completion */
        writel(mgtcr, &regs->phymntnc);
 
-       err = wait_for_bit(__func__, &regs->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
-                           true, 20000, true);
+       err = wait_for_bit_le32(&regs->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
+                               true, 20000, false);
        if (err)
                return err;
 
@@ -339,7 +338,7 @@ static int zynq_phy_init(struct udevice *dev)
        if (!priv->phydev)
                return -ENODEV;
 
-       priv->phydev->supported = supported | ADVERTISED_Pause |
+       priv->phydev->supported &= supported | ADVERTISED_Pause |
                                  ADVERTISED_Asym_Pause;
        priv->phydev->advertising = priv->phydev->supported;
 
@@ -409,10 +408,6 @@ static int zynq_gem_init(struct udevice *dev)
                dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK |
                                ZYNQ_GEM_RXBUF_NEW_MASK;
                dummy_rx_bd->status = 0;
-               flush_dcache_range((ulong)&dummy_tx_bd, (ulong)&dummy_tx_bd +
-                                  sizeof(dummy_tx_bd));
-               flush_dcache_range((ulong)&dummy_rx_bd, (ulong)&dummy_rx_bd +
-                                  sizeof(dummy_rx_bd));
 
                writel((ulong)dummy_tx_bd, &regs->transmit_q1_ptr);
                writel((ulong)dummy_rx_bd, &regs->receive_q1_ptr);
@@ -431,7 +426,12 @@ static int zynq_gem_init(struct udevice *dev)
 
        nwconfig = ZYNQ_GEM_NWCFG_INIT;
 
-       if (priv->interface == PHY_INTERFACE_MODE_SGMII) {
+       /*
+        * Set SGMII enable PCS selection only if internal PCS/PMA
+        * core is used and interface is SGMII.
+        */
+       if (priv->interface == PHY_INTERFACE_MODE_SGMII &&
+           priv->int_pcs) {
                nwconfig |= ZYNQ_GEM_NWCFG_SGMII_ENBL |
                            ZYNQ_GEM_NWCFG_PCS_SEL;
 #ifdef CONFIG_ARM64
@@ -456,7 +456,6 @@ static int zynq_gem_init(struct udevice *dev)
                break;
        }
 
-#if defined(CONFIG_CLK) || defined(CONFIG_SPL_CLK)
        ret = clk_set_rate(&priv->clk, clk_rate);
        if (IS_ERR_VALUE(ret) && ret != (unsigned long)-ENOSYS) {
                dev_err(dev, "failed to set tx clock rate\n");
@@ -468,10 +467,6 @@ static int zynq_gem_init(struct udevice *dev)
                dev_err(dev, "failed to enable tx clock\n");
                return ret;
        }
-#else
-       zynq_slcr_gem_clk_setup((ulong)priv->iobase !=
-                               ZYNQ_GEM_BASEADDR0, clk_rate);
-#endif
 
        setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
                                        ZYNQ_GEM_NWCTRL_TXEN_MASK);
@@ -519,8 +514,8 @@ static int zynq_gem_send(struct udevice *dev, void *ptr, int len)
        if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_EXHAUSTED)
                printf("TX buffers exhausted in mid frame\n");
 
-       return wait_for_bit(__func__, &regs->txsr, ZYNQ_GEM_TSR_DONE,
-                           true, 20000, true);
+       return wait_for_bit_le32(&regs->txsr, ZYNQ_GEM_TSR_DONE,
+                                true, 20000, true);
 }
 
 /* Do not check frame_recd flag in rx_status register 0x20 - just poll BD */
@@ -594,14 +589,12 @@ __weak int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
 
 static int zynq_gem_read_rom_mac(struct udevice *dev)
 {
-       int retval;
        struct eth_pdata *pdata = dev_get_platdata(dev);
 
-       retval = zynq_board_read_rom_ethaddr(pdata->enetaddr);
-       if (retval == -ENOSYS)
-               retval = 0;
+       if (!pdata)
+               return -ENOSYS;
 
-       return retval;
+       return zynq_board_read_rom_ethaddr(pdata->enetaddr);
 }
 
 static int zynq_gem_miiphy_read(struct mii_dev *bus, int addr,
@@ -644,13 +637,11 @@ static int zynq_gem_probe(struct udevice *dev)
        priv->tx_bd = (struct emac_bd *)bd_space;
        priv->rx_bd = (struct emac_bd *)((ulong)bd_space + BD_SEPRN_SPACE);
 
-#if defined(CONFIG_CLK) || defined(CONFIG_SPL_CLK)
        ret = clk_get_by_name(dev, "tx_clk", &priv->clk);
        if (ret < 0) {
                dev_err(dev, "failed to get clock\n");
                return -EINVAL;
        }
-#endif
 
        priv->bus = mdio_alloc();
        priv->bus->read = zynq_gem_miiphy_read;
@@ -692,7 +683,7 @@ static int zynq_gem_ofdata_to_platdata(struct udevice *dev)
        int node = dev_of_offset(dev);
        const char *phy_mode;
 
-       pdata->iobase = (phys_addr_t)dev_get_addr(dev);
+       pdata->iobase = (phys_addr_t)devfdt_get_addr(dev);
        priv->iobase = (struct zynq_gem_regs *)pdata->iobase;
        /* Hardcode for now */
        priv->phyaddr = -1;
@@ -712,6 +703,9 @@ static int zynq_gem_ofdata_to_platdata(struct udevice *dev)
        }
        priv->interface = pdata->phy_interface;
 
+       priv->int_pcs = fdtdec_get_bool(gd->fdt_blob, node,
+                                       "is-internal-pcspma");
+
        printf("ZYNQ GEM: %lx, phyaddr %x, interface %s\n", (ulong)priv->iobase,
               priv->phyaddr, phy_string_for_interface(priv->interface));