From patchwork Thu Jun 14 12:35:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 138568 Delivered-To: patch@linaro.org Received: by 2002:a2e:970d:0:0:0:0:0 with SMTP id r13-v6csp2058611lji; Thu, 14 Jun 2018 05:37:59 -0700 (PDT) X-Google-Smtp-Source: ADUXVKImqjsdXfO+a6V3+4jgGxNHgw2XjyotMTUT8Xu3FLegsgwgLZzlaspf69lnCe5HGS1qubwf X-Received: by 2002:a17:902:7105:: with SMTP id a5-v6mr2839589pll.171.1528979879464; Thu, 14 Jun 2018 05:37:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528979879; cv=none; d=google.com; s=arc-20160816; b=YGDPjqzT2z/SXfSf2RM5tcohyc2gGjw4cwZDPOYjvwrQhDmQVgcMSxW72okwaQVtv2 bItrIuK4aQvgMyRqkclvdUKq+Rb5euC6qwiCzcjjgVwj23zn/g+f5sR+Oeq7+gZrL0cj 5BsEPjdQc1fMe2qvzPv0OFB41LNLPTtXcSQuF6sYkfifi25o03pLuoU21nyYVX6uFo7r 2ywalxnnQfP83O870a6wx4gonQUzhf3jS0gVu4wHn3blWuV/NRvjIK5Llrot8pFMD7Gn OLKoCMrwaH9GZDkh5bqhVgu+aLLKkdkxnAgsegU6IlEIiT+pvERFbZMRgY2Ztk/TZLbD MZVQ== 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=rQ0JJl5i5LVb+Dr0uaB5UuHUmo2PrOTGrOEwWdIqSI0=; b=fpz9Fxc9SUNuXpekRNrIg478xUvipTayT8Ehd/c9xoSYXQy6cvK99Scie4Qa8gtDXs usE7gYHGgVQZwfQ+QrwnXiQ7E3SjgwrncXBAA4X9Hj6T8ebneN3xLr7Qc1wVW3Qf8OrP zvzqUrMzyr759Pcdpl2ZOOnwCVHn4WEISWwTCy0oVj/27sQrCkSwpMJN9WM7Sq7sXONH NZ3wAZ1oNm+Yh31i7XCFE7HfWOKpOjz/kF2y7ibTjWrYUZ0nJjOOv+U3aICEURyooz9p 3S8rb0SNen2KVrPV+v1isXj6pANJdwGsENx1F6+nR5fwaMSG95FIlPncfcHX5c6O7xRD B6UA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=cJEUU3tX; 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 e72-v6si5462466pfd.352.2018.06.14.05.37.59; Thu, 14 Jun 2018 05:37:59 -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=cJEUU3tX; 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 S934507AbeFNMh4 (ORCPT + 9 others); Thu, 14 Jun 2018 08:37:56 -0400 Received: from mail-lf0-f65.google.com ([209.85.215.65]:40674 "EHLO mail-lf0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755161AbeFNMhy (ORCPT ); Thu, 14 Jun 2018 08:37:54 -0400 Received: by mail-lf0-f65.google.com with SMTP id q11-v6so9172121lfc.7 for ; Thu, 14 Jun 2018 05:37:53 -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=rQ0JJl5i5LVb+Dr0uaB5UuHUmo2PrOTGrOEwWdIqSI0=; b=cJEUU3tXrjLZ66HFGJ5gN4Q6JUwUnZkfpSFE00tPbjIUI6Wg3CV9NMpwVmV60c+gA8 PDyj7QT1/k4mliMy3H5tge+dZOaCMloN71t45YcB1tyhpjbzjVfMdG92//DXN6IAv0kn 613dswrExiyxlebdMr5xosYGR1Bax30sO8fik= 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=rQ0JJl5i5LVb+Dr0uaB5UuHUmo2PrOTGrOEwWdIqSI0=; b=KUmkTVQDZmTdHiOS+8SLlYKEMHel+tjSJdR0thcypXjanXSDIs6v4mVKtnWBWp92FL i6BkOnSxCAbsSuAtf4ODMLmxEVV2o2MKDe0i01D9jOLN+i5KPSLCibU6KM0T+5FA1KWP ugtjAWbSQfFB3OegOadd2vA3smJ9+S4bz5khAscD1ar0xmezLJ95Tu+MtVCJiLtQwEJF ZhObuL3Yt6tM2Kmeh+DuiFACW+TgBN4fbycKnucsPAGau1rUca2PPVf6f8gVFk726fwO O/5dtMteWFdEBQbSG/ktlf8kgNMkO7k826n/aEYuan8d4TKFO9ysyWmuaEFky7CHr3Fe bOog== X-Gm-Message-State: APt69E11XdT9NiOLvnSSgMsB4cRbcBIzQ/8d1zSKEPcpm07kpEOPimRX fYcDHK5OYf5wegaQfRDrQ8C9Kg== X-Received: by 2002:a19:12c7:: with SMTP id 68-v6mr6307023lfs.10.1528979872391; Thu, 14 Jun 2018 05:37:52 -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 g17-v6sm937152ljg.27.2018.06.14.05.37.50 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 14 Jun 2018 05:37:51 -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] net: phy: vitesse: Add support for VSC73xx Date: Thu, 14 Jun 2018 14:35:33 +0200 Message-Id: <20180614123534.8063-3-linus.walleij@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180614123534.8063-1-linus.walleij@linaro.org> References: <20180614123534.8063-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. Signed-off-by: Linus Walleij --- drivers/net/phy/vitesse.c | 162 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) -- 2.17.1 Reviewed-by: Florian Fainelli diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index d9dd8fbfffc7..526c71ae7d96 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c @@ -16,6 +16,7 @@ #include #include #include +#include #include /* Vitesse Extended Page Magic Register(s) */ @@ -72,6 +73,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 +121,127 @@ 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, 0x1b, 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, 0x03); + 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); +} + /* 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 +444,38 @@ 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, + .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, + .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, + .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, + .read_page = vsc73xx_read_page, + .write_page = vsc73xx_write_page, }, { .phy_id = PHY_ID_VSC8662, .name = "Vitesse VSC8662", @@ -358,6 +516,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 },