From patchwork Sat Jun 30 11:17:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 140672 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp1895065ljj; Sat, 30 Jun 2018 04:23:20 -0700 (PDT) X-Google-Smtp-Source: AAOMgpc1kKJbNM12MElLDAQVddFpOxyit1t2eoBPDUCIzUiZ5geP/iE6hk8Iz6KYz06KvyFVxyAc X-Received: by 2002:a65:614a:: with SMTP id o10-v6mr4175963pgv.387.1530357800263; Sat, 30 Jun 2018 04:23:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530357800; cv=none; d=google.com; s=arc-20160816; b=OcMqXqLT6TN7AoOxl2F44Z/fohU9UZgKIweu1cs41lTz/aF8gfGt5UWldxGY+ah3h6 rqeVhIJyBu7GW3zpv/t7Zh0T8G4rg6Idtfarw5Rf6HCiZx0D95QSgd8vWckdL6oW4NRp S2VuEOJTWoXMso09y+TmOW0fLBodRJoh3F65nE9aobrTyEJtaIM7BcdsKJeuknN2D/zY BLQCHdo4EbpTfF4LvpzDFI7DnDenKjJ72+kakiEngx7o9RNNEqRllpo0bzdsURHEd1HY Ar7vyBXBvTEBnWNui0RRFWqPwECNLZW1uhB9UzeE+3DgsnU+P8hAYGQeFv/WcgWk047s 7GXw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=G1HUt3HGfzyvy6j7VemNSFcWapyMaDBoBA9loPjmrkI=; b=Z8onFyaQGDOfVdKbQFPe/XU2fueTsYSNhgLosfixqgCoRzNY1wXGH54lAk9XZ0zDKw IPWFKeqLEarlqUy+BsrreBgzhuCNNYdDnUKXaldBQ+jw7P7oRd1bCtF4CGJA9lprns9R kCx2iCdFzUetuSV6ZGooHj3DPwy/cpKxRkGHynSkBONYIsgK17dg1eAXC0PbsIKcfaMh QcTBowO3fWrfwOaBllY8CgKnQwI1TWO4Tu4HMC0WYOmSIWhPnOmtjHhxjF+Y+QPfqHBO p5cZn/qLcAMuc40OndylWWZNiCojM7qfPZNN9n53b9o0kxcFaDmbpC64fxTLD0UX1Ifi Yf/g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=MnPY6d4U; spf=pass (google.com: best guess record for domain of netdev-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f90-v6si11971061pfe.291.2018.06.30.04.23.20; Sat, 30 Jun 2018 04:23:20 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of netdev-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=MnPY6d4U; spf=pass (google.com: best guess record for domain of netdev-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=netdev-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1030374AbeF3LXS (ORCPT + 9 others); Sat, 30 Jun 2018 07:23:18 -0400 Received: from mail-lf0-f65.google.com ([209.85.215.65]:36596 "EHLO mail-lf0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1030203AbeF3LXQ (ORCPT ); Sat, 30 Jun 2018 07:23:16 -0400 Received: by mail-lf0-f65.google.com with SMTP id n24-v6so8610867lfh.3 for ; Sat, 30 Jun 2018 04:23:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=G1HUt3HGfzyvy6j7VemNSFcWapyMaDBoBA9loPjmrkI=; b=MnPY6d4UH9uH+AoOdAJ4F92/ngu4m0bDHYfjpzgai+wS5Qcd5sldPVTBUjlaWw9Oir yn2vHnMRUvgo784Uq65RxiozfVhOtwQXVvfXJWmhHDVJdTKNL8x4it5eYM3y+EGziaw7 djjNoE2Wvpi+X+kg0U4cWYJFjMMMio1f95qm0= 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=G1HUt3HGfzyvy6j7VemNSFcWapyMaDBoBA9loPjmrkI=; b=P98H4drpsyUDdxwT3UKEdc6X65/MH5Wl7AeaI1RPsm7q+vBoyrfBBFue3WccjLvO8/ Egy0T1SSusYXb4Uo97kYWqjGTkfLu54We/dfj+F4i2IF/zDAxT0IhSg9cfOxtlXSW4js 12zqNBgz3u3d7fmGYPiORfSZwTzSx6owq/FKJliWSmEjm1+ZjhBrPmkmkk2DFgYYLIPs om6Q7AcADlrWc7HSsTfx0keBk7BjGL0g5D7eW0sRH2UFh7VeCRJoUyc+HrDWCsY1+/Il oPfTCKz6mu7mWJsg3LlX2mIuQKZtYE0O8ju1l4Z58EvSM/+RmQF1MF8wAAJ/pPyRgxk3 geYw== X-Gm-Message-State: APt69E22FY0pLYtBciOeCz/s79XCf0fJsy2YqRtY81wCF91FuJdll99d cbUu1hAdQoW5p/HjWn63ZfjiAw== X-Received: by 2002:a19:dd5c:: with SMTP id u89-v6mr11797057lfg.83.1530357795259; Sat, 30 Jun 2018 04:23:15 -0700 (PDT) Received: from localhost.localdomain (c-ae7b71d5.014-348-6c756e10.bbcust.telenor.se. [213.113.123.174]) by smtp.gmail.com with ESMTPSA id s80-v6sm2157188lfg.89.2018.06.30.04.23.13 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 30 Jun 2018 04:23:14 -0700 (PDT) From: Linus Walleij To: Andrew Lunn , Vivien Didelot , Florian Fainelli Cc: netdev@vger.kernel.org, openwrt-devel@lists.openwrt.org, LEDE Development List , Gabor Juhos , Linus Walleij Subject: [PATCH 2/3 v2] net: phy: vitesse: Add support for VSC73xx Date: Sat, 30 Jun 2018 13:17:30 +0200 Message-Id: <20180630111731.19551-2-linus.walleij@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180630111731.19551-1-linus.walleij@linaro.org> References: <20180630111731.19551-1-linus.walleij@linaro.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The VSC7385, VSC7388, VSC7395 and VSC7398 are integrated switch/router chips for 5+1 or 8-port switches/routers. When managed directly by Linux using DSA we need to do a special set-up "dance" on the PHY. Unfortunately these sequences switches the PHY to undocumented pages named 2a30 and 52b6 and does undocumented things. It is described by these opaque sequences also in the reference manual. This is a best effort to integrate it anyways. Reviewed-by: Florian Fainelli Signed-off-by: Linus Walleij --- ChangeLog v1->v2: - Drop from an earlier iteration. - Implement an .config_aneg() routine that does nothing: the imroved genphy_config_aneg() makes the device fail as of v4.18-rc1 and the device seems to feel best like this: it comes up in autonegotiation mode and we do not try to instruct it. - Use some MII defines when reading/writing registers. - Collect Florian's ACK. --- drivers/net/phy/vitesse.c | 175 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) -- 2.17.1 diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index d9dd8fbfffc7..fbf9ad429593 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c @@ -72,6 +72,10 @@ #define PHY_ID_VSC8572 0x000704d0 #define PHY_ID_VSC8574 0x000704a0 #define PHY_ID_VSC8601 0x00070420 +#define PHY_ID_VSC7385 0x00070450 +#define PHY_ID_VSC7388 0x00070480 +#define PHY_ID_VSC7395 0x00070550 +#define PHY_ID_VSC7398 0x00070580 #define PHY_ID_VSC8662 0x00070660 #define PHY_ID_VSC8221 0x000fc550 #define PHY_ID_VSC8211 0x000fc4b0 @@ -116,6 +120,137 @@ static int vsc824x_config_init(struct phy_device *phydev) return err; } +#define VSC73XX_EXT_PAGE_ACCESS 0x1f + +static int vsc73xx_read_page(struct phy_device *phydev) +{ + return __phy_read(phydev, VSC73XX_EXT_PAGE_ACCESS); +} + +static int vsc73xx_write_page(struct phy_device *phydev, int page) +{ + return __phy_write(phydev, VSC73XX_EXT_PAGE_ACCESS, page); +} + +static void vsc73xx_config_init(struct phy_device *phydev) +{ + /* Receiver init */ + phy_write(phydev, 0x1f, 0x2a30); + phy_modify(phydev, 0x0c, 0x0300, 0x0200); + phy_write(phydev, 0x1f, 0x0000); + + /* Config LEDs 0x61 */ + phy_modify(phydev, MII_TPISTATUS, 0xff00, 0x0061); +} + +static int vsc738x_config_init(struct phy_device *phydev) +{ + u16 rev; + /* This magic sequence appear in the application note + * "VSC7385/7388 PHY Configuration". + * + * Maybe one day we will get to know what it all means. + */ + phy_write(phydev, 0x1f, 0x2a30); + phy_modify(phydev, 0x08, 0x0200, 0x0200); + phy_write(phydev, 0x1f, 0x52b5); + phy_write(phydev, 0x10, 0xb68a); + phy_modify(phydev, 0x12, 0xff07, 0x0003); + phy_modify(phydev, 0x11, 0x00ff, 0x00a2); + phy_write(phydev, 0x10, 0x968a); + phy_write(phydev, 0x1f, 0x2a30); + phy_modify(phydev, 0x08, 0x0200, 0x0000); + phy_write(phydev, 0x1f, 0x0000); + + /* Read revision */ + rev = phy_read(phydev, MII_PHYSID2); + rev &= 0x0f; + + /* Special quirk for revision 0 */ + if (rev == 0) { + phy_write(phydev, 0x1f, 0x2a30); + phy_modify(phydev, 0x08, 0x0200, 0x0200); + phy_write(phydev, 0x1f, 0x52b5); + phy_write(phydev, 0x12, 0x0000); + phy_write(phydev, 0x11, 0x0689); + phy_write(phydev, 0x10, 0x8f92); + phy_write(phydev, 0x1f, 0x52b5); + phy_write(phydev, 0x12, 0x0000); + phy_write(phydev, 0x11, 0x0e35); + phy_write(phydev, 0x10, 0x9786); + phy_write(phydev, 0x1f, 0x2a30); + phy_modify(phydev, 0x08, 0x0200, 0x0000); + phy_write(phydev, 0x17, 0xff80); + phy_write(phydev, 0x17, 0x0000); + } + + phy_write(phydev, 0x1f, 0x0000); + phy_write(phydev, 0x12, 0x0048); + + if (rev == 0) { + phy_write(phydev, 0x1f, 0x2a30); + phy_write(phydev, 0x14, 0x6600); + phy_write(phydev, 0x1f, 0x0000); + phy_write(phydev, 0x18, 0xa24e); + } else { + phy_write(phydev, 0x1f, 0x2a30); + phy_modify(phydev, 0x16, 0x0fc0, 0x0240); + phy_modify(phydev, 0x14, 0x6000, 0x4000); + /* bits 14-15 in extended register 0x14 controls DACG amplitude + * 6 = -8%, 2 is hardware default + */ + phy_write(phydev, 0x1f, 0x0001); + phy_modify(phydev, 0x14, 0xe000, 0x6000); + phy_write(phydev, 0x1f, 0x0000); + } + + vsc73xx_config_init(phydev); + + return genphy_config_init(phydev); +} + +static int vsc739x_config_init(struct phy_device *phydev) +{ + /* This magic sequence appears in the VSC7395 SparX-G5e application + * note "VSC7395/VSC7398 PHY Configuration" + * + * Maybe one day we will get to know what it all means. + */ + phy_write(phydev, 0x1f, 0x2a30); + phy_modify(phydev, 0x08, 0x0200, 0x0200); + phy_write(phydev, 0x1f, 0x52b5); + phy_write(phydev, 0x10, 0xb68a); + phy_modify(phydev, 0x12, 0xff07, 0x0003); + phy_modify(phydev, 0x11, 0x00ff, 0x00a2); + phy_write(phydev, 0x10, 0x968a); + phy_write(phydev, 0x1f, 0x2a30); + phy_modify(phydev, 0x08, 0x0200, 0x0000); + phy_write(phydev, 0x1f, 0x0000); + + phy_write(phydev, 0x1f, 0x0000); + phy_write(phydev, 0x12, 0x0048); + phy_write(phydev, 0x1f, 0x2a30); + phy_modify(phydev, 0x16, 0x0fc0, 0x0240); + phy_modify(phydev, 0x14, 0x6000, 0x4000); + phy_write(phydev, 0x1f, 0x0001); + phy_modify(phydev, 0x14, 0xe000, 0x6000); + phy_write(phydev, 0x1f, 0x0000); + + vsc73xx_config_init(phydev); + + return genphy_config_init(phydev); +} + +static int vsc73xx_config_aneg(struct phy_device *phydev) +{ + /* The VSC73xx switches does not like to be instructed to + * do autonegotiation in any way, it prefers that you just go + * with the power-on/reset defaults. Writing some registers will + * just make autonegotiation permanently fail. + */ + return 0; +} + /* This adds a skew for both TX and RX clocks, so the skew should only be * applied to "rgmii-id" interfaces. It may not work as expected * on "rgmii-txid", "rgmii-rxid" or "rgmii" interfaces. */ @@ -318,6 +453,42 @@ static struct phy_driver vsc82xx_driver[] = { .config_init = &vsc8601_config_init, .ack_interrupt = &vsc824x_ack_interrupt, .config_intr = &vsc82xx_config_intr, +}, { + .phy_id = PHY_ID_VSC7385, + .name = "Vitesse VSC7385", + .phy_id_mask = 0x000ffff0, + .features = PHY_GBIT_FEATURES, + .config_init = vsc738x_config_init, + .config_aneg = vsc73xx_config_aneg, + .read_page = vsc73xx_read_page, + .write_page = vsc73xx_write_page, +}, { + .phy_id = PHY_ID_VSC7388, + .name = "Vitesse VSC7388", + .phy_id_mask = 0x000ffff0, + .features = PHY_GBIT_FEATURES, + .config_init = vsc738x_config_init, + .config_aneg = vsc73xx_config_aneg, + .read_page = vsc73xx_read_page, + .write_page = vsc73xx_write_page, +}, { + .phy_id = PHY_ID_VSC7395, + .name = "Vitesse VSC7395", + .phy_id_mask = 0x000ffff0, + .features = PHY_GBIT_FEATURES, + .config_init = vsc739x_config_init, + .config_aneg = vsc73xx_config_aneg, + .read_page = vsc73xx_read_page, + .write_page = vsc73xx_write_page, +}, { + .phy_id = PHY_ID_VSC7398, + .name = "Vitesse VSC7398", + .phy_id_mask = 0x000ffff0, + .features = PHY_GBIT_FEATURES, + .config_init = vsc739x_config_init, + .config_aneg = vsc73xx_config_aneg, + .read_page = vsc73xx_read_page, + .write_page = vsc73xx_write_page, }, { .phy_id = PHY_ID_VSC8662, .name = "Vitesse VSC8662", @@ -358,6 +529,10 @@ static struct mdio_device_id __maybe_unused vitesse_tbl[] = { { PHY_ID_VSC8514, 0x000ffff0 }, { PHY_ID_VSC8572, 0x000ffff0 }, { PHY_ID_VSC8574, 0x000ffff0 }, + { PHY_ID_VSC7385, 0x000ffff0 }, + { PHY_ID_VSC7388, 0x000ffff0 }, + { PHY_ID_VSC7395, 0x000ffff0 }, + { PHY_ID_VSC7398, 0x000ffff0 }, { PHY_ID_VSC8662, 0x000ffff0 }, { PHY_ID_VSC8221, 0x000ffff0 }, { PHY_ID_VSC8211, 0x000ffff0 },