From patchwork Fri Jun 11 20:05:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12316561 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6CFC5C48BD1 for ; Fri, 11 Jun 2021 20:48:37 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 35DEE611B0 for ; Fri, 11 Jun 2021 20:48:37 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 35DEE611B0 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Nu0aEnowK2OAQFckMIQBakgkjfyUfsBp7BlUCAZU96M=; b=lSt2woff7BDhH1 4RTZPEZ31szMTC+zpxNAisLsW+6noSlWtPzaJQKYPz3uTZj5yFj8PeJXVfX8kmlU4qeTPDlF6lfno ROSESspUwgWnh/uF48R45PEW50txfOrDYNBMHV5t2VLfsf1O7vOwY59KE7naohXEpzrszY2h9cRot 39vcFrUSJFU4mUG8/FAR4LJFiJuGGIcVXxisopUgG2VKcWZfcOOUO2EvyqWK8PDP6dN+zApMiPOYl 1rZVG3JuCKmGMcJnWi5l4FtRrlhKm1V/tAZNN99NdsTaQqEyy8GTt5Tm5qzQJWIIkKgB0xogBiju6 a3UVBpe0V1qKJplR2J5Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1lro2i-006zFA-Oa; Fri, 11 Jun 2021 20:46:17 +0000 Received: from mail-ej1-f51.google.com ([209.85.218.51]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1lrnQi-006ozt-4P for linux-arm-kernel@lists.infradead.org; Fri, 11 Jun 2021 20:07:02 +0000 Received: by mail-ej1-f51.google.com with SMTP id h24so6274548ejy.2 for ; Fri, 11 Jun 2021 13:06:59 -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 :mime-version:content-transfer-encoding; bh=EfORNi+2Y2IKStIxZVTIGwtIaR3EJi0T8JfetVJhwU0=; b=SwWcBuKv5Vavo13i1ICqUAK+7Hik8s6tZkCUjYhCzuEJAwPuzukWOpZshRkkTO5rj+ YYsMgem73W28j5t8KAiZIiUjgtwbdVmjnc/U0m4ZquWrQIspZBtPL+z9pDkgRGKtpseC CjiwtDLGI9KWWNx82OIFvrmMfm1rIpAD9WLbDqfd+cyGlSztPVPRbTZgifGiPzgoTqW2 LCC3Xf43JHn+SR8Pl97QVD9rHPxqhBMNZLjjMgLV3Ex26CX6mfnMfkhPUMF2kH5MNe90 PsEynIODnLh77fUMcdWKCaAtyeIOGKgI+XxB3DayVujKb4sizf3VLYQZrRylQu+i4fJ9 dLzw== 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=EfORNi+2Y2IKStIxZVTIGwtIaR3EJi0T8JfetVJhwU0=; b=hctUyjNgF9fws8faReuLqDdJFWtf42Db4udQTV/cTrMCusqksKjEkC4/k8/02jF94H haxlAHUWlmDde21pf0UOwqT3diaTE1f0b8kg/jNoHviP15O736/2Y5r6TuEvgISNsO5S 3Xh7+4+paZDNmbfiDgtR1s/TebVAm7y/Os46RkHfTRAop3lhDLlAqS5XzAlw7Uw2JvzC /s94F7rNdAxEhAUwKr0uh5TIxPOMNI5vuMLkzrKkZdnEMxYAupnrgbDupmFcvey8Hjfg PZzi+tzMQ9MY4o+ER7HxhQydY011ypi6WtLT+Hoxo/RAVdr76NlxVrTrV0mQ60yGhHNb y/YA== X-Gm-Message-State: AOAM532HDmxY4OMILhApnlXLpvDmD8t990d+u+h7srLgwEWpRCtwrq4Z ahlrn2ZBynOXKBVuSlLUclI= X-Google-Smtp-Source: ABdhPJzP+vA9jb3DGIIGNJu3qJRUppbCQmTk41Hm+JZ5EO3/+30XmMBx//AnVQouc4e1DSZdEWxhpg== X-Received: by 2002:a17:906:2c1b:: with SMTP id e27mr5205367ejh.5.1623441958199; Fri, 11 Jun 2021 13:05:58 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id w2sm2392084ejn.118.2021.06.11.13.05.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Jun 2021 13:05:57 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Wong Vee Khee , Ong Boon Leong , Michael Sit Wei Hong , Giuseppe Cavallaro , Alexandre Torgue , Jose Abreu , Jose Abreu , Maxime Coquelin , Heiner Kallweit , Russell King - ARM Linux admin , Florian Fainelli , Andrew Lunn , Vivien Didelot , linux-arm-kernel@lists.infradead.org, linux-stm32@st-md-mailman.stormreply.com, Vladimir Oltean Subject: [PATCH v3 net-next 08/13] net: pcs: xpcs: add support for NXP SJA1110 Date: Fri, 11 Jun 2021 23:05:26 +0300 Message-Id: <20210611200531.2384819-9-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210611200531.2384819-1-olteanv@gmail.com> References: <20210611200531.2384819-1-olteanv@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210611_130700_267094_9654DE89 X-CRM114-Status: GOOD ( 20.80 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Vladimir Oltean The NXP SJA1110 switch integrates its own, non-Synopsys PMA, but it manages it through the register space of the XPCS itself, in a small register window inside MDIO_MMD_VEND2 from address 0x8030 to 0x806e. This coincides with where the registers for the default Synopsys PMA are, but the register definitions are of course not the same. This situation is an odd hardware quirk, but the simplest way to manage it is to drive the SJA1110's PMA from within the XPCS driver. Signed-off-by: Vladimir Oltean --- v2->v3: none v1->v2: none drivers/net/pcs/pcs-xpcs-nxp.c | 169 +++++++++++++++++++++++++++++++++ drivers/net/pcs/pcs-xpcs.c | 21 ++++ drivers/net/pcs/pcs-xpcs.h | 2 + include/linux/pcs/pcs-xpcs.h | 1 + 4 files changed, 193 insertions(+) diff --git a/drivers/net/pcs/pcs-xpcs-nxp.c b/drivers/net/pcs/pcs-xpcs-nxp.c index 51b2fc7d36a9..de99c37cf2ae 100644 --- a/drivers/net/pcs/pcs-xpcs-nxp.c +++ b/drivers/net/pcs/pcs-xpcs-nxp.c @@ -4,6 +4,66 @@ #include #include "pcs-xpcs.h" +/* LANE_DRIVER1_0 register */ +#define SJA1110_LANE_DRIVER1_0 0x8038 +#define SJA1110_TXDRV(x) (((x) << 12) & GENMASK(14, 12)) + +/* LANE_DRIVER2_0 register */ +#define SJA1110_LANE_DRIVER2_0 0x803a +#define SJA1110_TXDRVTRIM_LSB(x) ((x) & GENMASK_ULL(15, 0)) + +/* LANE_DRIVER2_1 register */ +#define SJA1110_LANE_DRIVER2_1 0x803b +#define SJA1110_LANE_DRIVER2_1_RSV BIT(9) +#define SJA1110_TXDRVTRIM_MSB(x) (((x) & GENMASK_ULL(23, 16)) >> 16) + +/* LANE_TRIM register */ +#define SJA1110_LANE_TRIM 0x8040 +#define SJA1110_TXTEN BIT(11) +#define SJA1110_TXRTRIM(x) (((x) << 8) & GENMASK(10, 8)) +#define SJA1110_TXPLL_BWSEL BIT(7) +#define SJA1110_RXTEN BIT(6) +#define SJA1110_RXRTRIM(x) (((x) << 3) & GENMASK(5, 3)) +#define SJA1110_CDR_GAIN BIT(2) +#define SJA1110_ACCOUPLE_RXVCM_EN BIT(0) + +/* LANE_DATAPATH_1 register */ +#define SJA1110_LANE_DATAPATH_1 0x8037 + +/* POWERDOWN_ENABLE register */ +#define SJA1110_POWERDOWN_ENABLE 0x8041 +#define SJA1110_TXPLL_PD BIT(12) +#define SJA1110_TXPD BIT(11) +#define SJA1110_RXPKDETEN BIT(10) +#define SJA1110_RXCH_PD BIT(9) +#define SJA1110_RXBIAS_PD BIT(8) +#define SJA1110_RESET_SER_EN BIT(7) +#define SJA1110_RESET_SER BIT(6) +#define SJA1110_RESET_DES BIT(5) +#define SJA1110_RCVEN BIT(4) + +/* RXPLL_CTRL0 register */ +#define SJA1110_RXPLL_CTRL0 0x8065 +#define SJA1110_RXPLL_FBDIV(x) (((x) << 2) & GENMASK(9, 2)) + +/* RXPLL_CTRL1 register */ +#define SJA1110_RXPLL_CTRL1 0x8066 +#define SJA1110_RXPLL_REFDIV(x) ((x) & GENMASK(4, 0)) + +/* TXPLL_CTRL0 register */ +#define SJA1110_TXPLL_CTRL0 0x806d +#define SJA1110_TXPLL_FBDIV(x) ((x) & GENMASK(11, 0)) + +/* TXPLL_CTRL1 register */ +#define SJA1110_TXPLL_CTRL1 0x806e +#define SJA1110_TXPLL_REFDIV(x) ((x) & GENMASK(5, 0)) + +/* RX_DATA_DETECT register */ +#define SJA1110_RX_DATA_DETECT 0x8045 + +/* RX_CDR_CTLE register */ +#define SJA1110_RX_CDR_CTLE 0x8042 + /* In NXP SJA1105, the PCS is integrated with a PMA that has the TX lane * polarity inverted by default (PLUS is MINUS, MINUS is PLUS). To obtain * normal non-inverted behavior, the TX lane polarity must be inverted in the @@ -14,3 +74,112 @@ int nxp_sja1105_sgmii_pma_config(struct dw_xpcs *xpcs) return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL2, DW_VR_MII_DIG_CTRL2_TX_POL_INV); } + +static int nxp_sja1110_pma_config(struct dw_xpcs *xpcs, + u16 txpll_fbdiv, u16 txpll_refdiv, + u16 rxpll_fbdiv, u16 rxpll_refdiv, + u16 rx_cdr_ctle) +{ + u16 val; + int ret; + + /* Program TX PLL feedback divider and reference divider settings for + * correct oscillation frequency. + */ + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_TXPLL_CTRL0, + SJA1110_TXPLL_FBDIV(txpll_fbdiv)); + if (ret < 0) + return ret; + + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_TXPLL_CTRL1, + SJA1110_TXPLL_REFDIV(txpll_refdiv)); + if (ret < 0) + return ret; + + /* Program transmitter amplitude and disable amplitude trimming */ + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_LANE_DRIVER1_0, + SJA1110_TXDRV(0x5)); + if (ret < 0) + return ret; + + val = SJA1110_TXDRVTRIM_LSB(0xffffffull); + + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_LANE_DRIVER2_0, val); + if (ret < 0) + return ret; + + val = SJA1110_TXDRVTRIM_MSB(0xffffffull) | SJA1110_LANE_DRIVER2_1_RSV; + + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_LANE_DRIVER2_1, val); + if (ret < 0) + return ret; + + /* Enable input and output resistor terminations for low BER. */ + val = SJA1110_ACCOUPLE_RXVCM_EN | SJA1110_CDR_GAIN | + SJA1110_RXRTRIM(4) | SJA1110_RXTEN | SJA1110_TXPLL_BWSEL | + SJA1110_TXRTRIM(3) | SJA1110_TXTEN; + + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_LANE_TRIM, val); + if (ret < 0) + return ret; + + /* Select PCS as transmitter data source. */ + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_LANE_DATAPATH_1, 0); + if (ret < 0) + return ret; + + /* Program RX PLL feedback divider and reference divider for correct + * oscillation frequency. + */ + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_RXPLL_CTRL0, + SJA1110_RXPLL_FBDIV(rxpll_fbdiv)); + if (ret < 0) + return ret; + + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_RXPLL_CTRL1, + SJA1110_RXPLL_REFDIV(rxpll_refdiv)); + if (ret < 0) + return ret; + + /* Program threshold for receiver signal detector. + * Enable control of RXPLL by receiver signal detector to disable RXPLL + * when an input signal is not present. + */ + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_RX_DATA_DETECT, 0x0005); + if (ret < 0) + return ret; + + /* Enable TX and RX PLLs and circuits. + * Release reset of PMA to enable data flow to/from PCS. + */ + val = xpcs_read(xpcs, MDIO_MMD_VEND2, SJA1110_POWERDOWN_ENABLE); + if (val < 0) + return val; + + val &= ~(SJA1110_TXPLL_PD | SJA1110_TXPD | SJA1110_RXCH_PD | + SJA1110_RXBIAS_PD | SJA1110_RESET_SER_EN | + SJA1110_RESET_SER | SJA1110_RESET_DES); + val |= SJA1110_RXPKDETEN | SJA1110_RCVEN; + + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_POWERDOWN_ENABLE, val); + if (ret < 0) + return ret; + + /* Program continuous-time linear equalizer (CTLE) settings. */ + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, SJA1110_RX_CDR_CTLE, + rx_cdr_ctle); + if (ret < 0) + return ret; + + return 0; +} + +int nxp_sja1110_sgmii_pma_config(struct dw_xpcs *xpcs) +{ + return nxp_sja1110_pma_config(xpcs, 0x19, 0x1, 0x19, 0x1, 0x212a); +} + +int nxp_sja1110_2500basex_pma_config(struct dw_xpcs *xpcs) +{ + return nxp_sja1110_pma_config(xpcs, 0x7d, 0x2, 0x7d, 0x2, 0x732a); +} diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c index 3b1baacfaf8f..b66e46fc88dc 100644 --- a/drivers/net/pcs/pcs-xpcs.c +++ b/drivers/net/pcs/pcs-xpcs.c @@ -1039,6 +1039,23 @@ static const struct xpcs_compat nxp_sja1105_xpcs_compat[DW_XPCS_INTERFACE_MAX] = }, }; +static const struct xpcs_compat nxp_sja1110_xpcs_compat[DW_XPCS_INTERFACE_MAX] = { + [DW_XPCS_SGMII] = { + .supported = xpcs_sgmii_features, + .interface = xpcs_sgmii_interfaces, + .num_interfaces = ARRAY_SIZE(xpcs_sgmii_interfaces), + .an_mode = DW_AN_C37_SGMII, + .pma_config = nxp_sja1110_sgmii_pma_config, + }, + [DW_XPCS_2500BASEX] = { + .supported = xpcs_2500basex_features, + .interface = xpcs_2500basex_interfaces, + .num_interfaces = ARRAY_SIZE(xpcs_2500basex_interfaces), + .an_mode = DW_2500BASEX, + .pma_config = nxp_sja1110_2500basex_pma_config, + }, +}; + static const struct xpcs_id xpcs_id_list[] = { { .id = SYNOPSYS_XPCS_ID, @@ -1048,6 +1065,10 @@ static const struct xpcs_id xpcs_id_list[] = { .id = NXP_SJA1105_XPCS_ID, .mask = SYNOPSYS_XPCS_MASK, .compat = nxp_sja1105_xpcs_compat, + }, { + .id = NXP_SJA1110_XPCS_ID, + .mask = SYNOPSYS_XPCS_MASK, + .compat = nxp_sja1110_xpcs_compat, }, }; diff --git a/drivers/net/pcs/pcs-xpcs.h b/drivers/net/pcs/pcs-xpcs.h index 3daf4276a158..35651d32a224 100644 --- a/drivers/net/pcs/pcs-xpcs.h +++ b/drivers/net/pcs/pcs-xpcs.h @@ -111,3 +111,5 @@ int xpcs_read(struct dw_xpcs *xpcs, int dev, u32 reg); int xpcs_write(struct dw_xpcs *xpcs, int dev, u32 reg, u16 val); int nxp_sja1105_sgmii_pma_config(struct dw_xpcs *xpcs); +int nxp_sja1110_sgmii_pma_config(struct dw_xpcs *xpcs); +int nxp_sja1110_2500basex_pma_config(struct dw_xpcs *xpcs); diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h index c594f7cdc304..dae7dd8ac683 100644 --- a/include/linux/pcs/pcs-xpcs.h +++ b/include/linux/pcs/pcs-xpcs.h @@ -11,6 +11,7 @@ #include #define NXP_SJA1105_XPCS_ID 0x00000010 +#define NXP_SJA1110_XPCS_ID 0x00000020 /* AN mode */ #define DW_AN_C73 1