Hi Michal, On Thu, Feb 1, 2018 at 6:42 AM, Michal Simek <michal.si...@xilinx.com> wrote: > Find out MDIO bus and enable MDIO access to it if this is done via > different controller. > > Signed-off-by: Michal Simek <michal.si...@xilinx.com> > --- > > Hi Joe, > > this is the code I have hacked a year ago for ZynqMP where we can have > configuration that 4 gems are enabled but they share the same MDIO bus > which can be assigned to only gem. Normally recommendation is that you > should assign it to IP which is required for boot and this is suitable I > would say for almost everybody. > But for testing purpose it will be good to support sharing mdio bus > between others IPs. This hack is "enabling" this for others gem but not > across different ethernet drivers.
Seems practical. > And my question is if there is any solution which can be used now for > handling it. Or even this should work even now but we do something > wrong. I would envision some DM way to model the NIC, the MDIO bus, and the PHY separately. The big roadblock is that the DTS format is different for every NIC. > I am refreshing this topic based on communication with Tomasz > Gorochowik when he wanted to separate mdio part but it is not compatible > with solution used in Linux which is pattern we should follow. We do the same thing on our 7020 products. > Note: I tested it only on zcu102 with the standard configuration but > Tomasz confirmed that this is still working with shared mdio bus. > > Thanks, > Michal > > --- > drivers/net/zynq_gem.c | 37 ++++++++++++++++++++++++++++++------- > 1 file changed, 30 insertions(+), 7 deletions(-) > > diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c > index 2cc49bca922a..33245ec36e67 100644 > --- a/drivers/net/zynq_gem.c > +++ b/drivers/net/zynq_gem.c > @@ -177,6 +177,7 @@ struct zynq_gem_priv { > int phyaddr; > int init; > struct zynq_gem_regs *iobase; > + struct zynq_gem_regs *mdiobase; > phy_interface_t interface; > struct phy_device *phydev; > int phy_of_handle; > @@ -189,7 +190,7 @@ static u32 phy_setup_op(struct zynq_gem_priv *priv, u32 > phy_addr, u32 regnum, > u32 op, u16 *data) > { > u32 mgtcr; > - struct zynq_gem_regs *regs = priv->iobase; > + struct zynq_gem_regs *regs = priv->mdiobase; > int err; > > err = wait_for_bit_le32(®s->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK, > @@ -314,7 +315,7 @@ static int zynq_phy_init(struct udevice *dev) > { > int ret; > struct zynq_gem_priv *priv = dev_get_priv(dev); > - struct zynq_gem_regs *regs = priv->iobase; > + struct zynq_gem_regs *regs_mdio = priv->mdiobase; > const u32 supported = SUPPORTED_10baseT_Half | > SUPPORTED_10baseT_Full | > SUPPORTED_100baseT_Half | > @@ -323,7 +324,7 @@ static int zynq_phy_init(struct udevice *dev) > SUPPORTED_1000baseT_Full; > > /* Enable only MDIO bus */ > - writel(ZYNQ_GEM_NWCTRL_MDEN_MASK, ®s->nwctrl); > + writel(ZYNQ_GEM_NWCTRL_MDEN_MASK, ®s_mdio->nwctrl); > > if (priv->interface != PHY_INTERFACE_MODE_SGMII) { > ret = phy_detection(dev); > @@ -355,6 +356,7 @@ static int zynq_gem_init(struct udevice *dev) > unsigned long clk_rate = 0; > struct zynq_gem_priv *priv = dev_get_priv(dev); > struct zynq_gem_regs *regs = priv->iobase; > + struct zynq_gem_regs *regs_mdio = priv->mdiobase; > struct emac_bd *dummy_tx_bd = &priv->tx_bd[TX_FREE_DESC]; > struct emac_bd *dummy_rx_bd = &priv->tx_bd[TX_FREE_DESC + 2]; > > @@ -397,7 +399,7 @@ static int zynq_gem_init(struct udevice *dev) > writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); > > /* Setup for Network Control register, MDIO, Rx and Tx enable > */ > - setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK); > + setbits_le32(®s_mdio->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK); > > /* Disable the second priority queue */ > dummy_tx_bd->addr = 0; > @@ -623,6 +625,7 @@ static int zynq_gem_probe(struct udevice *dev) > void *bd_space; > struct zynq_gem_priv *priv = dev_get_priv(dev); > int ret; > + char name[MDIO_NAME_LEN]; > > /* Align rxbuffers to ARCH_DMA_MINALIGN */ > priv->rxbuffers = memalign(ARCH_DMA_MINALIGN, RX_BUF * PKTSIZE_ALIGN); > @@ -648,6 +651,9 @@ static int zynq_gem_probe(struct udevice *dev) > priv->bus->write = zynq_gem_miiphy_write; > priv->bus->priv = priv; > > + snprintf(name, MDIO_NAME_LEN, "gem%lx", (ulong)priv->iobase); > + strncpy(priv->bus->name, name, MDIO_NAME_LEN); > + > ret = mdio_register_seq(priv->bus, dev->seq); > if (ret) > return ret; > @@ -682,6 +688,8 @@ static int zynq_gem_ofdata_to_platdata(struct udevice > *dev) > struct zynq_gem_priv *priv = dev_get_priv(dev); > int node = dev_of_offset(dev); > const char *phy_mode; > + fdt_addr_t addr; > + int parent; > > pdata->iobase = (phys_addr_t)devfdt_get_addr(dev); > priv->iobase = (struct zynq_gem_regs *)pdata->iobase; > @@ -690,10 +698,24 @@ static int zynq_gem_ofdata_to_platdata(struct udevice > *dev) > > priv->phy_of_handle = fdtdec_lookup_phandle(gd->fdt_blob, node, > "phy-handle"); > - if (priv->phy_of_handle > 0) > + if (priv->phy_of_handle > 0) { > priv->phyaddr = fdtdec_get_int(gd->fdt_blob, > priv->phy_of_handle, "reg", -1); > > + parent = fdt_parent_offset(gd->fdt_blob, priv->phy_of_handle); > + addr = fdtdec_get_addr(gd->fdt_blob, parent, "reg"); > + > + if (addr == FDT_ADDR_T_NONE) { > + printf("MDIO bus not found %x %x, %x\n", > + node, priv->phy_of_handle, parent); > + return -ENODEV; > + } > + > + priv->mdiobase = (struct zynq_gem_regs *)addr; > + } else { > + priv->mdiobase = priv->iobase; > + } > + > phy_mode = fdt_getprop(gd->fdt_blob, node, "phy-mode", NULL); > if (phy_mode) > pdata->phy_interface = phy_get_interface_by_name(phy_mode); > @@ -706,8 +728,9 @@ static int zynq_gem_ofdata_to_platdata(struct udevice > *dev) > 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)); > + printf("ZYNQ GEM: %lx, mdio bus %lx, phyaddr %d, interface %s\n", > + (ulong)priv->iobase, (ulong)priv->mdiobase, priv->phyaddr, > + phy_string_for_interface(priv->interface)); > > return 0; > } > -- > 1.9.1 > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > https://lists.denx.de/listinfo/u-boot _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot