From patchwork Sat Apr 25 11:51:45 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 464491 X-Patchwork-Delegate: hdegoede@redhat.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id A54901400B7 for ; Sat, 25 Apr 2015 21:52:37 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A9DF44BDF2; Sat, 25 Apr 2015 13:52:24 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id tVK08hp1yqvB; Sat, 25 Apr 2015 13:52:24 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id DDE754BE0E; Sat, 25 Apr 2015 13:52:13 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 30E6C4BDDF for ; Sat, 25 Apr 2015 13:52:07 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Jm7zUN0VSHEo for ; Sat, 25 Apr 2015 13:52:07 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by theia.denx.de (Postfix) with ESMTPS id 120524BDDD for ; Sat, 25 Apr 2015 13:52:05 +0200 (CEST) Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t3PBprHI019188 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Sat, 25 Apr 2015 07:51:54 -0400 Received: from shalem.localdomain.com (vpn1-6-3.ams2.redhat.com [10.36.6.3]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t3PBpnRT013362; Sat, 25 Apr 2015 07:51:52 -0400 From: Hans de Goede To: Ian Campbell , Simon Glass , Stefan Roese Date: Sat, 25 Apr 2015 13:51:45 +0200 Message-Id: <1429962708-12065-2-git-send-email-hdegoede@redhat.com> In-Reply-To: <1429962708-12065-1-git-send-email-hdegoede@redhat.com> References: <1429962708-12065-1-git-send-email-hdegoede@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH v2 1/4] sunxi: emac: port to phylib X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 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" This is a preparation-patch for adding device-model support to the emac driver. Signed-off-by: Hans de Goede --- drivers/net/sunxi_emac.c | 111 +++++++++++++++++++++++++---------------- include/configs/sunxi-common.h | 2 + 2 files changed, 71 insertions(+), 42 deletions(-) diff --git a/drivers/net/sunxi_emac.c b/drivers/net/sunxi_emac.c index 7b31f8c..b9fd1b8 100644 --- a/drivers/net/sunxi_emac.c +++ b/drivers/net/sunxi_emac.c @@ -156,9 +156,9 @@ struct sunxi_sramc_regs { #define DMA_CPU_TRRESHOLD 2000 struct emac_eth_dev { - u32 speed; - u32 duplex; - u32 phy_configured; + struct emac_regs *regs; + struct mii_dev *bus; + struct phy_device *phydev; int link_printed; }; @@ -195,11 +195,10 @@ static void emac_outblk_32bit(void *reg, void *data, int count) } /* Read a word from phyxcer */ -static int emac_phy_read(const char *devname, unsigned char addr, - unsigned char reg, unsigned short *value) +static int emac_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) { - struct eth_device *dev = eth_get_dev_by_name(devname); - struct emac_regs *regs = (struct emac_regs *)dev->iobase; + struct emac_eth_dev *priv = bus->priv; + struct emac_regs *regs = priv->regs; /* issue the phy address and reg */ writel(addr << 8 | reg, ®s->mac_madr); @@ -213,18 +212,16 @@ static int emac_phy_read(const char *devname, unsigned char addr, /* push down the phy io line */ writel(0x0, ®s->mac_mcmd); - /* and write data */ - *value = readl(®s->mac_mrdd); - - return 0; + /* And read data */ + return readl(®s->mac_mrdd); } /* Write a word to phyxcer */ -static int emac_phy_write(const char *devname, unsigned char addr, - unsigned char reg, unsigned short value) +static int emac_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, + u16 value) { - struct eth_device *dev = eth_get_dev_by_name(devname); - struct emac_regs *regs = (struct emac_regs *)dev->iobase; + struct emac_eth_dev *priv = bus->priv; + struct emac_regs *regs = priv->regs; /* issue the phy address and reg */ writel(addr << 8 | reg, ®s->mac_madr); @@ -244,12 +241,44 @@ static int emac_phy_write(const char *devname, unsigned char addr, return 0; } -static void emac_setup(struct eth_device *dev) +static int sunxi_emac_init_phy(struct emac_eth_dev *priv, void *dev) { - struct emac_regs *regs = (struct emac_regs *)dev->iobase; + int ret, mask = 0xffffffff; + +#ifdef CONFIG_PHY_ADDR + mask = 1 << CONFIG_PHY_ADDR; +#endif + + priv->bus = mdio_alloc(); + if (!priv->bus) { + printf("Failed to allocate MDIO bus\n"); + return -ENOMEM; + } + + priv->bus->read = emac_mdio_read; + priv->bus->write = emac_mdio_write; + priv->bus->priv = priv; + strcpy(priv->bus->name, "emac"); + + ret = mdio_register(priv->bus); + if (ret) + return ret; + + priv->phydev = phy_find_by_mask(priv->bus, mask, + PHY_INTERFACE_MODE_MII); + if (!priv->phydev) + return -ENODEV; + + phy_connect_dev(priv->phydev, dev); + phy_config(priv->phydev); + + return 0; +} + +static void emac_setup(struct emac_eth_dev *priv) +{ + struct emac_regs *regs = priv->regs; u32 reg_val; - u16 phy_val; - u32 duplex_flag; /* Set up TX */ writel(EMAC_TX_SETUP, ®s->tx_mode); @@ -262,12 +291,8 @@ static void emac_setup(struct eth_device *dev) writel(EMAC_MAC_CTL0_SETUP, ®s->mac_ctl0); /* Set MAC CTL1 */ - emac_phy_read(dev->name, 1, 0, &phy_val); - debug("PHY SETUP, reg 0 value: %x\n", phy_val); - duplex_flag = !!(phy_val & (1 << 8)); - reg_val = 0; - if (duplex_flag) + if (priv->phydev->duplex == DUPLEX_FULL) reg_val = (0x1 << 0); writel(EMAC_MAC_CTL1_SETUP | reg_val, ®s->mac_ctl1); @@ -302,7 +327,7 @@ static int sunxi_emac_eth_init(struct eth_device *dev, bd_t *bd) { struct emac_regs *regs = (struct emac_regs *)dev->iobase; struct emac_eth_dev *priv = dev->priv; - u16 phy_reg; + int ret; /* Init EMAC */ @@ -320,7 +345,7 @@ static int sunxi_emac_eth_init(struct eth_device *dev, bd_t *bd) udelay(1); /* Set up EMAC */ - emac_setup(dev); + emac_setup(priv); writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 | dev->enetaddr[2], ®s->mac_a1); @@ -332,29 +357,32 @@ static int sunxi_emac_eth_init(struct eth_device *dev, bd_t *bd) emac_reset(dev); /* PHY POWER UP */ - emac_phy_read(dev->name, 1, 0, &phy_reg); - emac_phy_write(dev->name, 1, 0, phy_reg & (~(0x1 << 11))); - mdelay(1); - - emac_phy_read(dev->name, 1, 0, &phy_reg); - - priv->speed = miiphy_speed(dev->name, 0); - priv->duplex = miiphy_duplex(dev->name, 0); + ret = phy_startup(priv->phydev); + if (ret) { + printf("Could not initialize PHY %s\n", + priv->phydev->dev->name); + return ret; + } /* Print link status only once */ if (!priv->link_printed) { printf("ENET Speed is %d Mbps - %s duplex connection\n", - priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL"); + priv->phydev->speed, + priv->phydev->duplex ? "FULL" : "HALF"); priv->link_printed = 1; } /* Set EMAC SPEED depend on PHY */ - clrsetbits_le32(®s->mac_supp, 1 << 8, - ((phy_reg & (0x1 << 13)) >> 13) << 8); + if (priv->phydev->speed == SPEED_100) + setbits_le32(®s->mac_supp, 1 << 8); + else + clrbits_le32(®s->mac_supp, 1 << 8); /* Set duplex depend on phy */ - clrsetbits_le32(®s->mac_ctl1, 1 << 0, - ((phy_reg & (0x1 << 8)) >> 8) << 0); + if (priv->phydev->duplex == DUPLEX_FULL) + setbits_le32(®s->mac_ctl1, 1 << 0); + else + clrbits_le32(®s->mac_ctl1, 1 << 0); /* Enable RX/TX */ setbits_le32(®s->ctl, 0x7); @@ -505,6 +533,7 @@ int sunxi_emac_initialize(void) /* Set MII clock */ clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2); + priv->regs = regs; dev->iobase = (int)regs; dev->priv = priv; dev->init = sunxi_emac_eth_init; @@ -515,7 +544,5 @@ int sunxi_emac_initialize(void) eth_register(dev); - miiphy_register(dev->name, emac_phy_read, emac_phy_write); - - return 0; + return sunxi_emac_init_phy(priv, dev); } diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index f97e626..40c7f63 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -350,7 +350,9 @@ extern int soft_i2c_gpio_scl; /* Ethernet support */ #ifdef CONFIG_SUNXI_EMAC +#define CONFIG_PHY_ADDR 1 #define CONFIG_MII /* MII PHY management */ +#define CONFIG_PHYLIB #endif #ifdef CONFIG_SUNXI_GMAC