From patchwork Wed Jun 27 10:06:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Packham X-Patchwork-Id: 935377 X-Patchwork-Delegate: sr@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="MVZWX59Z"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41Fz9w6DK1z9s0w for ; Wed, 27 Jun 2018 20:07:48 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 6EBCEC21DAF; Wed, 27 Jun 2018 10:07:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id B1401C21DA1; Wed, 27 Jun 2018 10:07:08 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 8C0A8C21D65; Wed, 27 Jun 2018 10:06:57 +0000 (UTC) Received: from mail-pl0-f65.google.com (mail-pl0-f65.google.com [209.85.160.65]) by lists.denx.de (Postfix) with ESMTPS id B1394C21C2C for ; Wed, 27 Jun 2018 10:06:51 +0000 (UTC) Received: by mail-pl0-f65.google.com with SMTP id w17-v6so806774pll.9 for ; Wed, 27 Jun 2018 03:06:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=TCBVDEz0MUujI4z6zNXwdK7gB0g6ZbCRC33wva+xMhk=; b=MVZWX59Z7kQs45FZ/PQd2r/3LgHII8NBs9jM8wliiPanLZtDaTUahVWD1qXtfhcD7S B7dPYgg8m54h4nf/V993LuNKhJ9dS+KyzaGYWqsK5dfQdgHbxVkWpNXjHQb6EozlTOvT hmOF1+RaByhfKf8DG/mXfCuHuxFBvmLexSLXUcmx++hP2sbsfrBlHU3+5UO2HYpyqpSK LX/kBgFFo2Jwaanpig1eH9VUuUpuNCpvZjHLgMbNfVWrMna3b39UQ3ayR3mU/oUB+iod Mwr7ZMqiIwE6bXHVZkwOoVH9JG8r+n/Bg5R4gDLeeur5+koC/fGg+gJ5Mjjwi8EwsOQF bepA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=TCBVDEz0MUujI4z6zNXwdK7gB0g6ZbCRC33wva+xMhk=; b=nVqweQCYqCyFmB28q9TtvFLJpHOgDpR2N6IWpfUIoOjtriEFxdNSQHf4zIgxtj1dD1 6p3zx2T1yUXV2dL9cBovkoNEWLU7Iqm7tHotMEPT7k0ZwIQq9ymon3FGp4AvmGcaX3GI KGhWdyMRSQJAOWCQmOHxm5Jrx/08s9zR/tT8lWmraVeC99PhFm8Vvxn6dnx5eaatCOW4 W15Q6d4WhRST7zG1PnaGVK5PwToOQ8orSAkjDkSFAbDRsw7mkU6dSYjA7H/3x10MQJs+ KDjNrQQsRod7vQBmYvgUedkfF1GjpwUnNY/3KyzME9ijCVq/WYdtANuFKQ6FgRZBfoCR 8auQ== X-Gm-Message-State: APt69E0AcmxxJq/zLMcqP+O6qNJzOzGegGLYHXBZPNtDXYu0nxYiXaJh 4gL0CaE+fODroeVW+3zrsia//djn X-Google-Smtp-Source: ADUXVKI1vBgk+NgpejFqM7az6LcQJo7jBqRHfl4uFXtfD6/v2DuidBpFFbN0b+ek9s0e7k8aMWlxSQ== X-Received: by 2002:a17:902:d88a:: with SMTP id b10-v6mr5560137plz.265.1530094010062; Wed, 27 Jun 2018 03:06:50 -0700 (PDT) Received: from chrisp-dl.ws.atlnz.lc ([2001:df5:b000:22:3a2c:4aff:fe70:2b02]) by smtp.gmail.com with ESMTPSA id w3-v6sm7976710pfi.109.2018.06.27.03.06.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 27 Jun 2018 03:06:49 -0700 (PDT) From: Chris Packham To: u-boot@lists.denx.de Date: Wed, 27 Jun 2018 22:06:28 +1200 Message-Id: <20180627100628.24603-2-judge.packham@gmail.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180627100628.24603-1-judge.packham@gmail.com> References: <20180627100628.24603-1-judge.packham@gmail.com> Cc: Tom Rini , Prafulla Wadaskar , Luka Perkov , Joe Hershberger , Stefan Roese , Chris Packham Subject: [U-Boot] [PATCH 2/2] net: mvgbe: convert to DM X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Add driver model support to the mvgbe driver. As a temporary measure both DM and non-DM uses are supported. Once all the users have been converted the non-DM support can be dropped. Signed-off-by: Chris Packham --- drivers/net/mvgbe.c | 201 +++++++++++++++++++++++++++++++++++++++++++- drivers/net/mvgbe.h | 16 ++++ 2 files changed, 213 insertions(+), 4 deletions(-) diff --git a/drivers/net/mvgbe.c b/drivers/net/mvgbe.c index 96ca35512f01..bddf2bc29aac 100644 --- a/drivers/net/mvgbe.c +++ b/drivers/net/mvgbe.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include @@ -127,8 +128,12 @@ static int __mvgbe_mdio_read(struct mvgbe_device *dmvgbe, int phy_adr, static int smi_reg_read(struct mii_dev *bus, int phy_adr, int devad, int reg_ofs) { +#ifdef CONFIG_DM_ETH + struct mvgbe_device *dmvgbe = bus->priv; +#else struct eth_device *dev = eth_get_dev_by_name(bus->name); struct mvgbe_device *dmvgbe = to_mvgbe(dev); +#endif return __mvgbe_mdio_read(dmvgbe, phy_adr, devad, reg_ofs); } @@ -180,8 +185,12 @@ static int __mvgbe_mdio_write(struct mvgbe_device *dmvgbe, int phy_adr, static int smi_reg_write(struct mii_dev *bus, int phy_adr, int devad, int reg_ofs, u16 data) { +#ifdef CONFIG_DM_ETH + struct mvgbe_device *dmvgbe = bus->priv; +#else struct eth_device *dev = eth_get_dev_by_name(bus->name); struct mvgbe_device *dmvgbe = to_mvgbe(dev); +#endif return __mvgbe_mdio_write(dmvgbe, phy_adr, devad, reg_ofs, data); } @@ -415,11 +424,12 @@ static void mvgbe_init_rx_desc_ring(struct mvgbe_device *dmvgbe) dmvgbe->p_rxdesc_curr = dmvgbe->p_rxdesc; } -static int __mvgbe_init(struct mvgbe_device *dmvgbe) +static int __mvgbe_init(struct mvgbe_device *dmvgbe, u8 *enetaddr) { struct mvgbe_registers *regs = dmvgbe->regs; #if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \ !defined(CONFIG_PHYLIB) && \ + !defined(CONFIG_DM_ETH) && \ defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) int i; #endif @@ -436,7 +446,7 @@ static int __mvgbe_init(struct mvgbe_device *dmvgbe) set_dram_access(regs); port_init_mac_tables(regs); - port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr); + port_uc_addr_set(dmvgbe, enetaddr); /* Assign port configuration and command. */ MVGBE_REG_WR(regs->pxc, PRT_CFG_VAL); @@ -473,6 +483,7 @@ static int __mvgbe_init(struct mvgbe_device *dmvgbe) #if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \ !defined(CONFIG_PHYLIB) && \ + !defined(CONFIG_DM_ETH) && \ defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) /* Wait up to 5s for the link status */ for (i = 0; i < 5; i++) { @@ -492,12 +503,14 @@ static int __mvgbe_init(struct mvgbe_device *dmvgbe) return 0; } +#ifndef CONFIG_DM_ETH static int mvgbe_init(struct eth_device *dev) { struct mvgbe_device *dmvgbe = to_mvgbe(dev); - return __mvgbe_init(dmvgbe); + return __mvgbe_init(dmvgbe, dmvgbe->dev.enetaddr); } +#endif static void __mvgbe_halt(struct mvgbe_device *dmvgbe) { @@ -524,6 +537,7 @@ static void __mvgbe_halt(struct mvgbe_device *dmvgbe) MVGBE_REG_WR(regs->peim, 0); } +#ifndef CONFIG_DM_ETH static int mvgbe_halt(struct eth_device *dev) { struct mvgbe_device *dmvgbe = to_mvgbe(dev); @@ -532,7 +546,18 @@ static int mvgbe_halt(struct eth_device *dev) return 0; } +#endif +#ifdef CONFIG_DM_ETH +static int mvgbe_write_hwaddr(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + + port_uc_addr_set(dev_get_priv(dev), pdata->enetaddr); + + return 0; +} +#else static int mvgbe_write_hwaddr(struct eth_device *dev) { struct mvgbe_device *dmvgbe = to_mvgbe(dev); @@ -541,6 +566,7 @@ static int mvgbe_write_hwaddr(struct eth_device *dev) port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr); return 0; } +#endif static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr, int datasize) @@ -597,12 +623,14 @@ static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr, return 0; } +#ifndef CONFIG_DM_ETH static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize) { struct mvgbe_device *dmvgbe = to_mvgbe(dev); return __mvgbe_send(dmvgbe, dataptr, datasize); } +#endif static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp) { @@ -677,6 +705,7 @@ static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp) return rx_bytes; } +#ifndef CONFIG_DM_ETH static int mvgbe_recv(struct eth_device *dev) { struct mvgbe_device *dmvgbe = to_mvgbe(dev); @@ -691,8 +720,9 @@ static int mvgbe_recv(struct eth_device *dev) return 0; } +#endif -#if defined(CONFIG_PHYLIB) +#if defined(CONFIG_PHYLIB) && !defined(CONFIG_DM_ETH) int mvgbe_phylib_init(struct eth_device *dev, int phyid) { struct mii_dev *bus; @@ -731,6 +761,7 @@ int mvgbe_phylib_init(struct eth_device *dev, int phyid) } #endif +#ifndef CONFIG_DM_ETH int mvgbe_initialize(bd_t *bis) { struct mvgbe_device *dmvgbe; @@ -834,3 +865,165 @@ error1: } return 0; } +#endif + +#ifdef CONFIG_DM_ETH +static int mvgbe_port_is_fixed_link(struct mvgbe_device *dmvgbe) +{ + return dmvgbe->phyaddr > PHY_MAX_ADDR; +} + +static int mvgbe_start(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + struct mvgbe_device *dmvgbe = dev_get_priv(dev); + struct phy_device *phydev; + int ret; + + ret = __mvgbe_init(dmvgbe, pdata->enetaddr); + if (ret) + return ret; + + if (!mvgbe_port_is_fixed_link(dmvgbe)) { + /* Set phy address of the port */ + miiphy_write(dev->name, MV_PHY_ADR_REQUEST, MV_PHY_ADR_REQUEST, + dmvgbe->phyaddr); + + phydev = phy_connect(dmvgbe->bus, dmvgbe->phyaddr, dev, + dmvgbe->phy_interface); + if (!phydev) { + printf("phy_connect failed\n"); + return -ENODEV; + } + + phy_config(phydev); + phy_startup(phydev); + } + + return 0; +} + +static int mvgbe_send(struct udevice *dev, void *packet, int length) +{ + struct mvgbe_device *dmvgbe = dev_get_priv(dev); + + return __mvgbe_send(dmvgbe, packet, length); +} + +static int mvgbe_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct mvgbe_device *dmvgbe = dev_get_priv(dev); + + return __mvgbe_recv(dmvgbe, packetp); +} + +static void mvgbe_stop(struct udevice *dev) +{ + struct mvgbe_device *dmvgbe = dev_get_priv(dev); + + __mvgbe_halt(dmvgbe); +} + +static int mvgbe_probe(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + struct mvgbe_device *dmvgbe = dev_get_priv(dev); + void *blob = (void *)gd->fdt_blob; + int node = dev_of_offset(dev); + struct mii_dev *bus; + unsigned long addr; + int ret; + int fl_node; + + dmvgbe->p_rxdesc = + (struct mvgbe_rxdesc *)memalign(PKTALIGN, + MV_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1); + dmvgbe->p_rxbuf = (u8 *)memalign(PKTALIGN, + RINGSZ * PKTSIZE_ALIGN + 1); + dmvgbe->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN); + dmvgbe->p_txdesc = (struct mvgbe_txdesc *)memalign( + PKTALIGN, sizeof(struct mvgbe_txdesc) + 1); + + dmvgbe->regs = (void __iomem *)pdata->iobase; + + /* PHY interface is already decoded in mvneta_ofdata_to_platdata() */ + dmvgbe->phy_interface = pdata->phy_interface; + + /* fetch 'fixed-link' property from 'neta' node */ + fl_node = fdt_subnode_offset(blob, node, "fixed-link"); + if (fl_node != -FDT_ERR_NOTFOUND) { + /* set phy_addr to invalid value for fixed link */ + dmvgbe->phyaddr = PHY_MAX_ADDR + 1; + dmvgbe->duplex = fdtdec_get_bool(blob, fl_node, "full-duplex"); + dmvgbe->speed = fdtdec_get_int(blob, fl_node, "speed", 0); + } else { + /* Now read phyaddr from DT */ + addr = fdtdec_get_int(blob, node, "phy", 0); + addr = fdt_node_offset_by_phandle(blob, addr); + dmvgbe->phyaddr = fdtdec_get_int(blob, addr, "reg", 0); + } + + bus = mdio_alloc(); + if (!bus) { + printf("Failed to allocate MDIO bus\n"); + return -ENOMEM; + } + + bus->read = smi_reg_read; + bus->write = smi_reg_write; + snprintf(bus->name, sizeof(bus->name), dev->name); + bus->priv = dmvgbe; + dmvgbe->bus = bus; + + ret = mdio_register(bus); + if (ret < 0) + return ret; + + return 0; +} + +static const struct eth_ops mvgbe_ops = { + .start = mvgbe_start, + .send = mvgbe_send, + .recv = mvgbe_recv, + .stop = mvgbe_stop, + .write_hwaddr = mvgbe_write_hwaddr, +}; + +static int mvgbe_ofdata_to_platdata(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + const char *phy_mode; + + pdata->iobase = devfdt_get_addr(dev); + + /* Get phy-mode / phy_interface from DT */ + pdata->phy_interface = -1; + phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode", + NULL); + if (phy_mode) + pdata->phy_interface = phy_get_interface_by_name(phy_mode); + if (pdata->phy_interface == -1) { + debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode); + return -EINVAL; + } + + return 0; +} + +static const struct udevice_id mvgbe_ids[] = { + { .compatible = "marvell,kirkwood-eth" }, + { } +}; + +U_BOOT_DRIVER(mvgbe) = { + .name = "mvgbe", + .id = UCLASS_ETH, + .of_match = mvgbe_ids, + .ofdata_to_platdata = mvgbe_ofdata_to_platdata, + .probe = mvgbe_probe, + .ops = &mvgbe_ops, + .priv_auto_alloc_size = sizeof(struct mvgbe_device), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), +}; +#endif /* CONFIG_DM_ETH */ diff --git a/drivers/net/mvgbe.h b/drivers/net/mvgbe.h index 1dc9bbea2f42..44541c0a85e3 100644 --- a/drivers/net/mvgbe.h +++ b/drivers/net/mvgbe.h @@ -30,7 +30,9 @@ #define RXUQ 0 /* Used Rx queue */ #define TXUQ 0 /* Used Rx queue */ +#ifndef CONFIG_DM_ETH #define to_mvgbe(_d) container_of(_d, struct mvgbe_device, dev) +#endif #define MVGBE_REG_WR(adr, val) writel(val, &adr) #define MVGBE_REG_RD(adr) readl(&adr) #define MVGBE_REG_BITS_RESET(adr, val) writel(readl(&adr) & ~(val), &adr) @@ -479,13 +481,27 @@ struct mvgbe_txdesc { /* port device data struct */ struct mvgbe_device { +#ifndef CONFIG_DM_ETH struct eth_device dev; +#endif struct mvgbe_registers *regs; struct mvgbe_txdesc *p_txdesc; struct mvgbe_rxdesc *p_rxdesc; struct mvgbe_rxdesc *p_rxdesc_curr; u8 *p_rxbuf; u8 *p_aligned_txbuf; + +#ifdef CONFIG_DM_ETH + phy_interface_t phy_interface; + unsigned int link; + unsigned int duplex; + unsigned int speed; + + int init; + int phyaddr; + struct phy_device *phydev; + struct mii_dev *bus; +#endif }; #endif /* __MVGBE_H__ */