From patchwork Fri Jan 12 07:51:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antoine Tenart X-Patchwork-Id: 10159761 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A6BC3602A7 for ; Fri, 12 Jan 2018 07:56:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 94732289A1 for ; Fri, 12 Jan 2018 07:56:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 86C36289A2; Fri, 12 Jan 2018 07:56:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C66EC205F8 for ; Fri, 12 Jan 2018 07:56:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=OVNMGmqOa0Y5UyzhzqllsJ8HmqNklrKZ9B7S5qQcsTQ=; b=l57oKz1Fs/aykauS88NKqrZ+Wv WRyDX5oeNPFlYXn3QaaMFUIcMLvJHGmR+HevftW9C7bW11NHXm9y/OdcUGRjRIovFRW3E9qEHBlep F1Fb6xMCixH+aSHQSk5fAbivN5Pxf+j3cMHD8sMlKx18fokR5upsjJhl9FTyk3CJhq1snVYQM5IWn JGp4bw72qdjsBRnwxwdhXnTDxb15fZzXdOZtle7zCF2IQsmDSIfhe2IIdSgdgWPvhzu4slVrvl4JG 2d0BTUsmJXm97S7wx747I450UF4ymHG3BHQmYPcBMx6X07OK13Kby2fu5VgHfsHCZK37gih9OEVBc ZvetDenw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1eZuCG-0006yb-GL; Fri, 12 Jan 2018 07:56:16 +0000 Received: from mail.free-electrons.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1eZuBE-0004oW-Um for linux-arm-kernel@lists.infradead.org; Fri, 12 Jan 2018 07:55:16 +0000 Received: by mail.free-electrons.com (Postfix, from userid 110) id 634692084D; Fri, 12 Jan 2018 08:55:02 +0100 (CET) Received: from localhost (nat.foo.tf [163.172.35.26]) by mail.free-electrons.com (Postfix) with ESMTPSA id 2FF82206A6; Fri, 12 Jan 2018 08:55:02 +0100 (CET) From: Antoine Tenart To: davem@davemloft.net, kishon@ti.com Subject: [PATCH net-next v5 4/4] net: mvpp2: 2500baseX support Date: Fri, 12 Jan 2018 08:51:30 +0100 Message-Id: <20180112075130.30890-5-antoine.tenart@free-electrons.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180112075130.30890-1-antoine.tenart@free-electrons.com> References: <20180112075130.30890-1-antoine.tenart@free-electrons.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180111_235513_342686_60E56D0E X-CRM114-Status: GOOD ( 14.90 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: thomas.petazzoni@free-electrons.com, andrew@lunn.ch, ymarkman@marvell.com, netdev@vger.kernel.org, Antoine Tenart , linux@armlinux.org.uk, linux-kernel@vger.kernel.org, nadavh@marvell.com, miquel.raynal@free-electrons.com, gregory.clement@free-electrons.com, stefanc@marvell.com, mw@semihalf.com, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds the 2500Base-X PHY mode support in the Marvell PPv2 driver. 2500Base-X is quite close to 1000Base-X and SGMII modes and uses nearly the same code path. Signed-off-by: Antoine Tenart Reviewed-by: Andrew Lunn --- drivers/net/ethernet/marvell/mvpp2.c | 49 ++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index 257a6b99b4ca..38f9a79481c6 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -4502,6 +4502,7 @@ static int mvpp22_gop_init(struct mvpp2_port *port) break; case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_1000BASEX: + case PHY_INTERFACE_MODE_2500BASEX: mvpp22_gop_init_sgmii(port); break; case PHY_INTERFACE_MODE_10GKR: @@ -4540,7 +4541,8 @@ static void mvpp22_gop_unmask_irq(struct mvpp2_port *port) if (phy_interface_mode_is_rgmii(port->phy_interface) || port->phy_interface == PHY_INTERFACE_MODE_SGMII || - port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) { + port->phy_interface == PHY_INTERFACE_MODE_1000BASEX || + port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) { /* Enable the GMAC link status irq for this port */ val = readl(port->base + MVPP22_GMAC_INT_SUM_MASK); val |= MVPP22_GMAC_INT_SUM_MASK_LINK_STAT; @@ -4571,7 +4573,8 @@ static void mvpp22_gop_mask_irq(struct mvpp2_port *port) if (phy_interface_mode_is_rgmii(port->phy_interface) || port->phy_interface == PHY_INTERFACE_MODE_SGMII || - port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) { + port->phy_interface == PHY_INTERFACE_MODE_1000BASEX || + port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) { val = readl(port->base + MVPP22_GMAC_INT_SUM_MASK); val &= ~MVPP22_GMAC_INT_SUM_MASK_LINK_STAT; writel(val, port->base + MVPP22_GMAC_INT_SUM_MASK); @@ -4584,7 +4587,8 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port) if (phy_interface_mode_is_rgmii(port->phy_interface) || port->phy_interface == PHY_INTERFACE_MODE_SGMII || - port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) { + port->phy_interface == PHY_INTERFACE_MODE_1000BASEX || + port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) { val = readl(port->base + MVPP22_GMAC_INT_MASK); val |= MVPP22_GMAC_INT_MASK_LINK_STAT; writel(val, port->base + MVPP22_GMAC_INT_MASK); @@ -4599,6 +4603,16 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port) mvpp22_gop_unmask_irq(port); } +/* Sets the PHY mode of the COMPHY (which configures the serdes lanes). + * + * The PHY mode used by the PPv2 driver comes from the network subsystem, while + * the one given to the COMPHY comes from the generic PHY subsystem. Hence they + * differ. + * + * The COMPHY configures the serdes lanes regardless of the actual use of the + * lanes by the physical layer. This is why configurations like + * "PPv2 (2500BaseX) - COMPHY (2500SGMII)" are valid. + */ static int mvpp22_comphy_init(struct mvpp2_port *port) { enum phy_mode mode; @@ -4612,6 +4626,9 @@ static int mvpp22_comphy_init(struct mvpp2_port *port) case PHY_INTERFACE_MODE_1000BASEX: mode = PHY_MODE_SGMII; break; + case PHY_INTERFACE_MODE_2500BASEX: + mode = PHY_MODE_2500SGMII; + break; case PHY_INTERFACE_MODE_10GKR: mode = PHY_MODE_10GKR; break; @@ -4631,7 +4648,8 @@ static void mvpp2_port_mii_gmac_configure_mode(struct mvpp2_port *port) u32 val; if (port->phy_interface == PHY_INTERFACE_MODE_SGMII || - port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) { + port->phy_interface == PHY_INTERFACE_MODE_1000BASEX || + port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) { val = readl(port->base + MVPP22_GMAC_CTRL_4_REG); val |= MVPP22_CTRL4_SYNC_BYPASS_DIS | MVPP22_CTRL4_DP_CLK_SEL | MVPP22_CTRL4_QSGMII_BYPASS_ACTIVE; @@ -4647,7 +4665,8 @@ static void mvpp2_port_mii_gmac_configure_mode(struct mvpp2_port *port) } val = readl(port->base + MVPP2_GMAC_CTRL_0_REG); - if (port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) + if (port->phy_interface == PHY_INTERFACE_MODE_1000BASEX || + port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) val |= MVPP2_GMAC_PORT_TYPE_MASK; else val &= ~MVPP2_GMAC_PORT_TYPE_MASK; @@ -4660,7 +4679,13 @@ static void mvpp2_port_mii_gmac_configure_mode(struct mvpp2_port *port) if (port->phy_interface == PHY_INTERFACE_MODE_SGMII) val |= MVPP2_GMAC_IN_BAND_AUTONEG; - if (port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) + /* Clear all fields we may want to explicitly set below */ + val &= ~(MVPP2_GMAC_CONFIG_FULL_DUPLEX | MVPP2_GMAC_CONFIG_GMII_SPEED | + MVPP2_GMAC_CONFIG_MII_SPEED | MVPP2_GMAC_AN_SPEED_EN | + MVPP2_GMAC_AN_DUPLEX_EN); + + if (port->phy_interface == PHY_INTERFACE_MODE_1000BASEX || + port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) /* 1000BaseX port cannot negotiate speed nor can it * negotiate duplex: they are always operating with a * fixed speed of 1000Mbps in full duplex, so force @@ -4693,7 +4718,8 @@ static void mvpp2_port_mii_gmac_configure(struct mvpp2_port *port) /* Configure the PCS and in-band AN */ val = readl(port->base + MVPP2_GMAC_CTRL_2_REG); if (port->phy_interface == PHY_INTERFACE_MODE_SGMII || - port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) { + port->phy_interface == PHY_INTERFACE_MODE_1000BASEX || + port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) { val |= MVPP2_GMAC_INBAND_AN_MASK | MVPP2_GMAC_PCS_ENABLE_MASK; } else if (phy_interface_mode_is_rgmii(port->phy_interface)) { val &= ~MVPP2_GMAC_PCS_ENABLE_MASK; @@ -4756,7 +4782,8 @@ static void mvpp2_port_mii_set(struct mvpp2_port *port) if (phy_interface_mode_is_rgmii(port->phy_interface) || port->phy_interface == PHY_INTERFACE_MODE_SGMII || - port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) + port->phy_interface == PHY_INTERFACE_MODE_1000BASEX || + port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) mvpp2_port_mii_gmac_configure(port); else if (port->phy_interface == PHY_INTERFACE_MODE_10GKR) mvpp2_port_mii_xlg_configure(port); @@ -4834,7 +4861,8 @@ static void mvpp2_port_loopback_set(struct mvpp2_port *port) val &= ~MVPP2_GMAC_GMII_LB_EN_MASK; if (port->phy_interface == PHY_INTERFACE_MODE_SGMII || - port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) + port->phy_interface == PHY_INTERFACE_MODE_1000BASEX || + port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) val |= MVPP2_GMAC_PCS_LB_EN_MASK; else val &= ~MVPP2_GMAC_PCS_LB_EN_MASK; @@ -6048,7 +6076,8 @@ static irqreturn_t mvpp2_link_status_isr(int irq, void *dev_id) } } else if (phy_interface_mode_is_rgmii(port->phy_interface) || port->phy_interface == PHY_INTERFACE_MODE_SGMII || - port->phy_interface == PHY_INTERFACE_MODE_1000BASEX) { + port->phy_interface == PHY_INTERFACE_MODE_1000BASEX || + port->phy_interface == PHY_INTERFACE_MODE_2500BASEX) { val = readl(port->base + MVPP22_GMAC_INT_STAT); if (val & MVPP22_GMAC_INT_STAT_LINK) { event = true;