From patchwork Fri Feb 8 17:25:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Carlo Caione X-Patchwork-Id: 1038818 X-Patchwork-Delegate: joe.hershberger@gmail.com 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=none (p=none dis=none) header.from=baylibre.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=baylibre-com.20150623.gappssmtp.com header.i=@baylibre-com.20150623.gappssmtp.com header.b="wYnfMQ13"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 43x2Fs2D25z9s4V for ; Sat, 9 Feb 2019 04:28:17 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id CE0A7C22018; Fri, 8 Feb 2019 17:27:34 +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=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 BB5FAC22043; Fri, 8 Feb 2019 17:26:50 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id D37F7C22044; Fri, 8 Feb 2019 17:26:00 +0000 (UTC) Received: from mail-wm1-f66.google.com (mail-wm1-f66.google.com [209.85.128.66]) by lists.denx.de (Postfix) with ESMTPS id CD4FDC22046 for ; Fri, 8 Feb 2019 17:25:59 +0000 (UTC) Received: by mail-wm1-f66.google.com with SMTP id d15so4297489wmb.3 for ; Fri, 08 Feb 2019 09:25:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=CvKwJK+RJaqaAPhGKEsxPNmr7m2qifBQxRwbxfLC77Q=; b=wYnfMQ13oZeBd1tKbqbGzaKxBfDre5sUbBYUMWIIyUkGNYu9JqNPgX1AGHkO2VkffA NOAmTNMQYKMzIr3EAhT4gS4gT5fVLuouF0HfoKoPgEBN+T1eLa6wL7HWR3O6SdvmDjae OFXFY3miqx6FqCw9xW5RIwHa2s+NdzoQ3L8yuBpa1PaVcUXXA46BXE0OV2B1yPXZKtWB vW/KVA7WX3zFzugrzEeNaQi1cnFelAob6+tg8OaRCrQH2t8eCmSkjE/JlFKTHqE5AQtU tG+KeN2KN2cHOncf+ci6x3OS+qsOadiLBMO0ytfv1y/IcThgS7wn+PGX3mwF9ihLc7M0 JKFw== 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:mime-version:content-transfer-encoding; bh=CvKwJK+RJaqaAPhGKEsxPNmr7m2qifBQxRwbxfLC77Q=; b=kDtcK1sOiqYjHvxOf3NGhsFd/gXTiBesWW8A+062nyQzCs06Tky3QlwLyuPx9AGDeV U/DhO3yYCJD2gTXD3X2QzFJDYrUVLL46umEWRLwXkOe6TvazN+zQpP9LfMQTrpiqb6sp GrdnnoKHLU3qvkh0rvs99073D1u6jAciZhfA894kiruZ3UboSOR+1Rf/YeVJQISQAJLR mWt6BfM0cv0pOqF36OColr3/IuynytHsVqlLLDFEvnD0dx8+KQskUid6Hl5CpB4Du6T4 tovAwIc6aoJB6TDAbwSi7mdx3AVYnYCb4R3ARP0SbBsoSOknmbDqJiRQZUxYoH8ieyje kAUA== X-Gm-Message-State: AHQUAuZFusXZK1R00EjZP/VjI9VMoG2ohSMt8M3zAUh4uF94+GyVbQs2 aG4tH83b5aUyQgll5RAtWb4l9Q== X-Google-Smtp-Source: AHgI3IbrlQGDsVApbtXfJKnPMUuyXFcOo8gJulWhgeTZqzJdtWkre0x7NeFtdGOsV1pvRsptKAcfcw== X-Received: by 2002:a7b:c14b:: with SMTP id z11mr7626056wmi.15.1549646759415; Fri, 08 Feb 2019 09:25:59 -0800 (PST) Received: from localhost.localdomain ([2a00:23c4:f7a1:ce00:5105:4b7b:c922:7c6]) by smtp.gmail.com with ESMTPSA id p4sm2580872wrs.74.2019.02.08.09.25.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 08 Feb 2019 09:25:58 -0800 (PST) From: Carlo Caione To: joe.hershberger@ni.com, joseph.hershberger@ni.com, vladimir.oltean@nxp.com, u-boot@lists.denx.de Date: Fri, 8 Feb 2019 17:25:06 +0000 Message-Id: <20190208172508.23601-2-ccaione@baylibre.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190208172508.23601-1-ccaione@baylibre.com> References: <20190208172508.23601-1-ccaione@baylibre.com> MIME-Version: 1.0 Cc: Carlo Caione Subject: [U-Boot] [PATCH v5 1/3] net: phy: Add generic helpers to access MMD PHY registers 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: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Two new helper functions (phy_read_mmd() and phy_write_mmd()) are added to allow access to the MMD PHY registers. The MMD PHY registers can be accessed by several means: 1. Using two new MMD access function hooks in the PHY driver. These functions can be implemented when the PHY driver does not support the standard IEEE Compatible clause 45 access mechanism described in clause 22 or if the PHY uses its own non-standard access mechanism. 2. Direct access for C45 PHYs and C22 PHYs when accessing the reachable DEVADs. 3. The standard clause 45 access extensions to the MMD registers through the indirection registers (clause 22) in all the other cases. Signed-off-by: Carlo Caione Acked-by: Joe Hershberger --- drivers/net/phy/phy.c | 4 +++ include/phy.h | 70 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index cda4caa803..6769047407 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -549,6 +549,10 @@ int phy_register(struct phy_driver *drv) drv->readext += gd->reloc_off; if (drv->writeext) drv->writeext += gd->reloc_off; + if (drv->read_mmd) + drv->read_mmd += gd->reloc_off; + if (drv->write_mmd) + drv->write_mmd += gd->reloc_off; #endif return 0; } diff --git a/include/phy.h b/include/phy.h index b86fdfb2ce..7ec2b4e86c 100644 --- a/include/phy.h +++ b/include/phy.h @@ -101,6 +101,14 @@ struct phy_driver { int (*readext)(struct phy_device *phydev, int addr, int devad, int reg); int (*writeext)(struct phy_device *phydev, int addr, int devad, int reg, u16 val); + + /* Phy specific driver override for reading a MMD register */ + int (*read_mmd)(struct phy_device *phydev, int devad, int reg); + + /* Phy specific driver override for writing a MMD register */ + int (*write_mmd)(struct phy_device *phydev, int devad, int reg, + u16 val); + struct list_head list; }; @@ -164,6 +172,68 @@ static inline int phy_write(struct phy_device *phydev, int devad, int regnum, return bus->write(bus, phydev->addr, devad, regnum, val); } +static inline void phy_mmd_start_indirect(struct phy_device *phydev, int devad, + int regnum) +{ + /* Write the desired MMD Devad */ + phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_CTRL, devad); + + /* Write the desired MMD register address */ + phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, regnum); + + /* Select the Function : DATA with no post increment */ + phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_CTRL, + (devad | MII_MMD_CTRL_NOINCR)); +} + +static inline int phy_read_mmd(struct phy_device *phydev, int devad, + int regnum) +{ + struct phy_driver *drv = phydev->drv; + + if (regnum > (u16)~0 || devad > 32) + return -EINVAL; + + /* driver-specific access */ + if (drv->read_mmd) + return drv->read_mmd(phydev, devad, regnum); + + /* direct C45 / C22 access */ + if ((drv->features & PHY_10G_FEATURES) == PHY_10G_FEATURES || + devad == MDIO_DEVAD_NONE || !devad) + return phy_read(phydev, devad, regnum); + + /* indirect C22 access */ + phy_mmd_start_indirect(phydev, devad, regnum); + + /* Read the content of the MMD's selected register */ + return phy_read(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA); +} + +static inline int phy_write_mmd(struct phy_device *phydev, int devad, + int regnum, u16 val) +{ + struct phy_driver *drv = phydev->drv; + + if (regnum > (u16)~0 || devad > 32) + return -EINVAL; + + /* driver-specific access */ + if (drv->write_mmd) + return drv->write_mmd(phydev, devad, regnum, val); + + /* direct C45 / C22 access */ + if ((drv->features & PHY_10G_FEATURES) == PHY_10G_FEATURES || + devad == MDIO_DEVAD_NONE || !devad) + return phy_write(phydev, devad, regnum, val); + + /* indirect C22 access */ + phy_mmd_start_indirect(phydev, devad, regnum); + + /* Write the data into MMD's selected register */ + return phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, val); +} + #ifdef CONFIG_PHYLIB_10G extern struct phy_driver gen10g_driver;