mediatek: add mt7531 DSA support
authorJohn Crispin <john@phrozen.org>
Thu, 4 Jun 2020 13:07:28 +0000 (15:07 +0200)
committerJohn Crispin <john@phrozen.org>
Sun, 7 Jun 2020 17:10:51 +0000 (19:10 +0200)
Signed-off-by: John Crispin <john@phrozen.org>
target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-rootdisk.dts
target/linux/mediatek/mt7622/base-files/etc/board.d/02_network
target/linux/mediatek/mt7622/config-5.4
target/linux/mediatek/patches-5.4/0600-1-6-net-dsa-mt7530-Refine-message-in-Kconfig.patch [new file with mode: 0644]
target/linux/mediatek/patches-5.4/0600-2-6-net-dsa-mt7530-Extend-device-data-ready-for-adding-a-new-hardware.patch [new file with mode: 0644]
target/linux/mediatek/patches-5.4/0600-3-6-dt-bindings-net-dsa-add-new-MT7531-binding-to-support-MT7531.patch [new file with mode: 0644]
target/linux/mediatek/patches-5.4/0600-4-6-net-dsa-mt7530-Add-the-support-of-MT7531-switch.patch [new file with mode: 0644]
target/linux/mediatek/patches-5.4/0600-6-6-arm64-dts-mt7622-add-mt7531-dsa-to-bananapi-bpi-r64-board.patch [new file with mode: 0644]

index 9d80366a18aa89ab273d865768777b2719e6eff7..6a14ef369b10594806f8941ce9b73dde56fdd683 100644 (file)
                };
        };
 
-       gsw: gsw@0 {
-               compatible = "mediatek,mt753x";
-               mediatek,ethsys = <&ethsys>;
-               #address-cells = <1>;
-               #size-cells = <0>;
-       };
-
        leds {
                compatible = "gpio-leds";
 
        mdio: mdio-bus {
                #address-cells = <1>;
                #size-cells = <0>;
-       };
-};
 
-&gsw {
-        mediatek,mdio = <&mdio>;
-        mediatek,portmap = "wllll";
-        mediatek,mdio_master_pinmux = <0>;
-        reset-gpios = <&pio 54 0>;
-        interrupt-parent = <&pio>;
-        interrupts = <53 IRQ_TYPE_LEVEL_HIGH>;
-        status = "okay";
-
-        port5: port@5 {
-                compatible = "mediatek,mt753x-port";
-                reg = <5>;
-                phy-mode = "rgmii";
-                fixed-link {
-                        speed = <1000>;
-                        full-duplex;
-                };
-        };
-
-        port6: port@6 {
-                compatible = "mediatek,mt753x-port";
-                reg = <6>;
-                phy-mode = "sgmii";
-                fixed-link {
-                        speed = <2500>;
-                        full-duplex;
-                };
-        };
+               switch@1f {
+                       compatible = "mediatek,mt7531";
+                       reg = <0x1f>;
+                       reset-gpios = <&pio 54 0>;
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               wan: port@0 {
+                                       reg = <0>;
+                                       label = "wan";
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       label = "lan0";
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+                                       label = "lan1";
+                               };
+
+                               port@3 {
+                                       reg = <3>;
+                                       label = "lan2";
+                               };
+
+                               port@4 {
+                                       reg = <4>;
+                                       label = "lan3";
+                               };
+
+                               port@6 {
+                                       reg = <6>;
+                                       label = "cpu";
+                                       ethernet = <&gmac0>;
+                                       phy-mode = "2500base-x";
+
+                                       fixed-link {
+                                               speed = <2500>;
+                                               full-duplex;
+                                               pause;
+                                       };
+                               };
+                       };
+               };
+
+       };
 };
 
 &i2c1 {
index b87a24fc2a212ead4fd7e7e6b12ac6c231a550c3..eed01a92939839d649bca7d1ff64157f0b4bd31c 100755 (executable)
@@ -9,6 +9,10 @@ mediatek_setup_interfaces()
        local board="$1"
 
        case $board in
+       bananapi,bpi-r64-rootdisk|\
+       bananapi,bpi-r64)
+               ucidef_set_interfaces_lan_wan "lan0 lan1 lan2 lan3" wan
+               ;;
        *)
                ucidef_add_switch "switch0" \
                                  "0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "6u@eth0" "5u@eth1"
index 040de2fbc01083b6627c4b65702eb0f82768b80a..1a00636968159567bcce088a317316d55d830e25 100755 (executable)
@@ -393,7 +393,7 @@ CONFIG_MMC_MTK=y
 # CONFIG_MMC_TIFM_SD is not set
 CONFIG_MODULES_TREE_LOOKUP=y
 CONFIG_MODULES_USE_ELF_RELA=y
-CONFIG_MT753X_GSW=y
+# CONFIG_MT753X_GSW is not set
 CONFIG_MTD_NAND_CORE=y
 CONFIG_MTD_NAND_ECC_SW_HAMMING=y
 CONFIG_MTD_NAND_MTK=y
@@ -415,8 +415,13 @@ CONFIG_MTK_TIMER=y
 CONFIG_MUTEX_SPIN_ON_OWNER=y
 CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_MT7530=y
+CONFIG_NET_DSA_TAG_MTK=y
 CONFIG_NET_FLOW_LIMIT=y
 CONFIG_NET_MEDIATEK_SOC=y
+CONFIG_NET_SWITCHDEV=y
 CONFIG_NET_VENDOR_MEDIATEK=y
 CONFIG_NLS=y
 CONFIG_NO_HZ_COMMON=y
diff --git a/target/linux/mediatek/patches-5.4/0600-1-6-net-dsa-mt7530-Refine-message-in-Kconfig.patch b/target/linux/mediatek/patches-5.4/0600-1-6-net-dsa-mt7530-Refine-message-in-Kconfig.patch
new file mode 100644 (file)
index 0000000..5c56765
--- /dev/null
@@ -0,0 +1,100 @@
+From patchwork Tue Dec 10 08:14:37 2019
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Landen Chao <landen.chao@mediatek.com>
+X-Patchwork-Id: 1206962
+X-Patchwork-Delegate: davem@davemloft.net
+Return-Path: <netdev-owner@vger.kernel.org>
+X-Original-To: patchwork-incoming-netdev@ozlabs.org
+Delivered-To: patchwork-incoming-netdev@ozlabs.org
+Authentication-Results: ozlabs.org; spf=none (no SPF record)
+ smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67;
+ helo=vger.kernel.org;
+ envelope-from=netdev-owner@vger.kernel.org;
+ receiver=<UNKNOWN>)
+Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none)
+ header.from=mediatek.com
+Authentication-Results: ozlabs.org; dkim=pass (1024-bit key;
+ unprotected) header.d=mediatek.com header.i=@mediatek.com
+ header.b="pTp2PPKi"; dkim-atps=neutral
+Received: from vger.kernel.org (vger.kernel.org [209.132.180.67])
+ by ozlabs.org (Postfix) with ESMTP id 47XCY42hJqz9sRf
+ for <patchwork-incoming-netdev@ozlabs.org>;
+ Tue, 10 Dec 2019 19:15:20 +1100 (AEDT)
+Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
+ id S1727061AbfLJIO5 (ORCPT
+ <rfc822;patchwork-incoming-netdev@ozlabs.org>);
+ Tue, 10 Dec 2019 03:14:57 -0500
+Received: from mailgw02.mediatek.com ([210.61.82.184]:45567 "EHLO
+ mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by
+ vger.kernel.org with ESMTP id S1726932AbfLJIO4 (ORCPT
+ <rfc822;netdev@vger.kernel.org>); Tue, 10 Dec 2019 03:14:56 -0500
+X-UUID: f5656f2ff80846ebb40e3da87d60fb90-20191210
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
+ d=mediatek.com; s=dk; 
+ h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From;
+ bh=THbuVAlbiUyMgTyO0rwrKX/mskzsxNwDv9gxXp2O2c8=; 
+ b=pTp2PPKiPwR8QPOOf5yohf9lFERpEDlo/g/t2ChREfzFb9c+wylx++/div4hAB337+Ja2KIzbSu4URgdj5XHXUly8yuxrD8OBvV+ox0jlNLiRIN2dkCgL4fyzPr7ZPSk9lObJW05Yx2LY6Jy6eJZZXSShLlqLd0lDKwy6FT+hSI=;
+X-UUID: f5656f2ff80846ebb40e3da87d60fb90-20191210
+Received: from mtkcas07.mediatek.inc [(172.21.101.84)] by
+ mailgw02.mediatek.com (envelope-from <landen.chao@mediatek.com>)
+ (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS)
+ with ESMTP id 565263134; Tue, 10 Dec 2019 16:14:47 +0800
+Received: from mtkcas08.mediatek.inc (172.21.101.126) by
+ mtkmbs07n1.mediatek.inc (172.21.101.16) with Microsoft SMTP Server
+ (TLS) id 15.0.1395.4; Tue, 10 Dec 2019 16:14:38 +0800
+Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas08.mediatek.inc
+ (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via
+ Frontend Transport; Tue, 10 Dec 2019 16:14:26 +0800
+From: Landen Chao <landen.chao@mediatek.com>
+To: <andrew@lunn.ch>, <f.fainelli@gmail.com>,
+ <vivien.didelot@savoirfairelinux.com>, <matthias.bgg@gmail.com>,
+ <robh+dt@kernel.org>, <mark.rutland@arm.com>
+CC: <devicetree@vger.kernel.org>, <netdev@vger.kernel.org>,
+ <linux-kernel@vger.kernel.org>,
+ <linux-mediatek@lists.infradead.org>, <davem@davemloft.net>,
+ <sean.wang@mediatek.com>, <opensource@vdorst.com>,
+ <frank-w@public-files.de>, Landen Chao <landen.chao@mediatek.com>
+Subject: [PATCH net-next 1/6] net: dsa: mt7530: Refine message in Kconfig
+Date: Tue, 10 Dec 2019 16:14:37 +0800
+Message-ID: <6ecf6cbf38223f35854bc361c2eefa1d85c724d2.1575914275.git.landen.chao@mediatek.com>
+X-Mailer: git-send-email 2.18.0
+In-Reply-To: <cover.1575914275.git.landen.chao@mediatek.com>
+References: <cover.1575914275.git.landen.chao@mediatek.com>
+MIME-Version: 1.0
+X-MTK: N
+Sender: netdev-owner@vger.kernel.org
+Precedence: bulk
+List-ID: <netdev.vger.kernel.org>
+X-Mailing-List: netdev@vger.kernel.org
+
+Refine message in Kconfig with fixing typo and an explicit MT7621 support.
+
+Signed-off-by: Landen Chao <landen.chao@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+---
+ drivers/net/dsa/Kconfig | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig\r
+index c7667645f04a..467f80157acf 100644\r
+--- a/drivers/net/dsa/Kconfig\r
++++ b/drivers/net/dsa/Kconfig\r
+@@ -33,12 +33,12 @@ config NET_DSA_LANTIQ_GSWIP\r
+         the xrx200 / VR9 SoC.\r
\r
+ config NET_DSA_MT7530\r
+-      tristate "Mediatek MT7530 Ethernet switch support"\r
++      tristate "MediaTek MT7530 and MT7621 Ethernet switch support"\r
+       depends on NET_DSA\r
+       select NET_DSA_TAG_MTK\r
+       ---help---\r
+-        This enables support for the Mediatek MT7530 Ethernet switch\r
+-        chip.\r
++        This enables support for the MediaTek MT7530 and MT7621 Ethernet\r
++        switch chip.\r
\r
+ config NET_DSA_MV88E6060\r
+       tristate "Marvell 88E6060 ethernet switch chip support"\r
diff --git a/target/linux/mediatek/patches-5.4/0600-2-6-net-dsa-mt7530-Extend-device-data-ready-for-adding-a-new-hardware.patch b/target/linux/mediatek/patches-5.4/0600-2-6-net-dsa-mt7530-Extend-device-data-ready-for-adding-a-new-hardware.patch
new file mode 100644 (file)
index 0000000..637f9e3
--- /dev/null
@@ -0,0 +1,445 @@
+From patchwork Tue Dec 10 08:14:38 2019
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Landen Chao <landen.chao@mediatek.com>
+X-Patchwork-Id: 1206963
+X-Patchwork-Delegate: davem@davemloft.net
+Return-Path: <netdev-owner@vger.kernel.org>
+X-Original-To: patchwork-incoming-netdev@ozlabs.org
+Delivered-To: patchwork-incoming-netdev@ozlabs.org
+Authentication-Results: ozlabs.org; spf=none (no SPF record)
+ smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67;
+ helo=vger.kernel.org;
+ envelope-from=netdev-owner@vger.kernel.org;
+ receiver=<UNKNOWN>)
+Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none)
+ header.from=mediatek.com
+Authentication-Results: ozlabs.org; dkim=pass (1024-bit key;
+ unprotected) header.d=mediatek.com header.i=@mediatek.com
+ header.b="UJ5NATux"; dkim-atps=neutral
+Received: from vger.kernel.org (vger.kernel.org [209.132.180.67])
+ by ozlabs.org (Postfix) with ESMTP id 47XCY92tBkz9sR7
+ for <patchwork-incoming-netdev@ozlabs.org>;
+ Tue, 10 Dec 2019 19:15:25 +1100 (AEDT)
+Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
+ id S1727003AbfLJIO4 (ORCPT
+ <rfc822;patchwork-incoming-netdev@ozlabs.org>);
+ Tue, 10 Dec 2019 03:14:56 -0500
+Received: from mailgw02.mediatek.com ([210.61.82.184]:45567 "EHLO
+ mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by
+ vger.kernel.org with ESMTP id S1726071AbfLJIOy (ORCPT
+ <rfc822;netdev@vger.kernel.org>); Tue, 10 Dec 2019 03:14:54 -0500
+X-UUID: a18674d7b33c423e9e67b7440f4771cf-20191210
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
+ d=mediatek.com; s=dk; 
+ h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From;
+ bh=c2C/fEHYw/8uqadmiP2m2xa2hsUpAd52urXVJTPlYck=; 
+ b=UJ5NATuxMtqHln5i6BTpWiLnxGKgWvp4DpRsKVO2xdnz2cJaT4XL8F/T5fK3CTF4nAai0EKPAcqp+rr8eCLq7uURJv5e5h+ZIzKLSAB4zgnchXesQLo0uFS8vs5w2yp49j6bez1z3v/uN+1+Lpq0uYid9awCqzvbnovrooEysu4=;
+X-UUID: a18674d7b33c423e9e67b7440f4771cf-20191210
+Received: from mtkcas09.mediatek.inc [(172.21.101.178)] by
+ mailgw02.mediatek.com (envelope-from <landen.chao@mediatek.com>)
+ (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS)
+ with ESMTP id 1965641267; Tue, 10 Dec 2019 16:14:46 +0800
+Received: from mtkcas08.mediatek.inc (172.21.101.126) by
+ mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server
+ (TLS) id 15.0.1395.4; Tue, 10 Dec 2019 16:14:31 +0800
+Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas08.mediatek.inc
+ (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via
+ Frontend Transport; Tue, 10 Dec 2019 16:14:26 +0800
+From: Landen Chao <landen.chao@mediatek.com>
+To: <andrew@lunn.ch>, <f.fainelli@gmail.com>,
+ <vivien.didelot@savoirfairelinux.com>, <matthias.bgg@gmail.com>,
+ <robh+dt@kernel.org>, <mark.rutland@arm.com>
+CC: <devicetree@vger.kernel.org>, <netdev@vger.kernel.org>,
+ <linux-kernel@vger.kernel.org>,
+ <linux-mediatek@lists.infradead.org>, <davem@davemloft.net>,
+ <sean.wang@mediatek.com>, <opensource@vdorst.com>,
+ <frank-w@public-files.de>, Landen Chao <landen.chao@mediatek.com>
+Subject: [PATCH net-next 2/6] net: dsa: mt7530: Extend device data ready for
+ adding a new hardware
+Date: Tue, 10 Dec 2019 16:14:38 +0800
+Message-ID: <2d546d6bb15ff8b4b75af2220e20db4e634f4145.1575914275.git.landen.chao@mediatek.com>
+X-Mailer: git-send-email 2.18.0
+In-Reply-To: <cover.1575914275.git.landen.chao@mediatek.com>
+References: <cover.1575914275.git.landen.chao@mediatek.com>
+MIME-Version: 1.0
+X-MTK: N
+Sender: netdev-owner@vger.kernel.org
+Precedence: bulk
+List-ID: <netdev.vger.kernel.org>
+X-Mailing-List: netdev@vger.kernel.org
+
+Add a structure holding required operations for each device such as device
+initialization, PHY port read or write, a checker whether PHY interface is
+supported on a certain port, MAC port setup for either bus pad or a
+specific PHY interface.
+
+The patch is done for ready adding a new hardware MT7531.
+
+Signed-off-by: Landen Chao <landen.chao@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+---
+ drivers/net/dsa/mt7530.c | 231 +++++++++++++++++++++++++++++----------
+ drivers/net/dsa/mt7530.h |  29 ++++-
+ 2 files changed, 203 insertions(+), 57 deletions(-)
+
+Index: linux-5.4.43/drivers/net/dsa/mt7530.c
+===================================================================
+--- linux-5.4.43.orig/drivers/net/dsa/mt7530.c
++++ linux-5.4.43/drivers/net/dsa/mt7530.c
+@@ -373,7 +373,7 @@ mt7530_fdb_write(struct mt7530_priv *pri
+ }
+ static int
+-mt7530_pad_clk_setup(struct dsa_switch *ds, int mode)
++mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t mode)
+ {
+       struct mt7530_priv *priv = ds->priv;
+       u32 ncpo1, ssc_delta, trgint, i, xtal;
+@@ -1355,13 +1355,111 @@ mt7530_setup(struct dsa_switch *ds)
+       return 0;
+ }
+-static void mt7530_phylink_mac_config(struct dsa_switch *ds, int port,
++static bool mt7530_phy_supported(struct dsa_switch *ds, int port,
++                               const struct phylink_link_state *state)
++{
++      struct mt7530_priv *priv = ds->priv;
++
++      switch (port) {
++      case 0: /* Internal phy */
++      case 1:
++      case 2:
++      case 3:
++      case 4:
++              if (state->interface != PHY_INTERFACE_MODE_GMII)
++                      goto unsupported;
++              break;
++      case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
++              if (!phy_interface_mode_is_rgmii(state->interface) &&
++                  state->interface != PHY_INTERFACE_MODE_MII &&
++                  state->interface != PHY_INTERFACE_MODE_GMII)
++                      goto unsupported;
++              break;
++      case 6: /* 1st cpu port */
++              if (state->interface != PHY_INTERFACE_MODE_RGMII &&
++                  state->interface != PHY_INTERFACE_MODE_TRGMII)
++                      goto unsupported;
++              break;
++      default:
++              dev_err(priv->dev, "%s: unsupported port: %i\n", __func__,
++                      port);
++              goto unsupported;
++      }
++
++      return true;
++
++unsupported:
++      return false;
++}
++
++static bool mt753x_phy_supported(struct dsa_switch *ds, int port,
++                               const struct phylink_link_state *state)
++{
++      struct mt7530_priv *priv = ds->priv;
++
++      return priv->info->phy_supported(ds, port, state);
++}
++
++static int
++mt7530_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
++{
++      struct mt7530_priv *priv = ds->priv;
++
++      /* Setup TX circuit incluing relevant PAD and driving */
++      mt7530_pad_clk_setup(ds, state->interface);
++
++      if (priv->id == ID_MT7530) {
++              /* Setup RX circuit, relevant PAD and driving on the
++               * host which must be placed after the setup on the
++               * device side is all finished.
++               */
++              mt7623_pad_clk_setup(ds);
++      }
++
++      return 0;
++}
++
++static int
++mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
++{
++      struct mt7530_priv *priv = ds->priv;
++
++      return priv->info->pad_setup(ds, state);
++}
++
++static int
++mt7530_mac_setup(struct dsa_switch *ds, int port, unsigned int mode,
++               const struct phylink_link_state *state)
++{
++      struct mt7530_priv *priv = ds->priv;
++
++      /* Only need to setup port5. */
++      if (port != 5)
++              return 0;
++
++      mt7530_setup_port5(priv->ds, state->interface);
++
++      return 0;
++}
++
++static int mt753x_mac_setup(struct dsa_switch *ds, int port, unsigned int mode,
++                          const struct phylink_link_state *state)
++{
++      struct mt7530_priv *priv = ds->priv;
++
++      return priv->info->mac_setup(ds, port, mode, state);
++}
++
++static void mt753x_phylink_mac_config(struct dsa_switch *ds, int port,
+                                     unsigned int mode,
+                                     const struct phylink_link_state *state)
+ {
+       struct mt7530_priv *priv = ds->priv;
+       u32 mcr_cur, mcr_new;
++      if (!mt753x_phy_supported(ds, port, state))
++              return;
++
+       switch (port) {
+       case 0: /* Internal phy */
+       case 1:
+@@ -1374,24 +1472,15 @@ static void mt7530_phylink_mac_config(st
+       case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
+               if (priv->p5_interface == state->interface)
+                       break;
+-              if (!phy_interface_mode_is_rgmii(state->interface) &&
+-                  state->interface != PHY_INTERFACE_MODE_MII &&
+-                  state->interface != PHY_INTERFACE_MODE_GMII)
+-                      return;
+-
+-              mt7530_setup_port5(ds, state->interface);
++              if (mt753x_mac_setup(ds, port, mode, state) < 0)
++                      goto unsupported;
+               break;
+       case 6: /* 1st cpu port */
+               if (priv->p6_interface == state->interface)
+                       break;
+-
+-              if (state->interface != PHY_INTERFACE_MODE_RGMII &&
+-                  state->interface != PHY_INTERFACE_MODE_TRGMII)
+-                      return;
+-
+-              /* Setup TX circuit incluing relevant PAD and driving */
+-              mt7530_pad_clk_setup(ds, state->interface);
+-
++              mt753x_pad_setup(ds, state);
++              if (mt753x_mac_setup(ds, port, mode, state) < 0)
++                      goto unsupported;
+               priv->p6_interface = state->interface;
+               break;
+       default:
+@@ -1459,38 +1548,14 @@ static void mt7530_phylink_mac_link_up(s
+       mt7530_port_set_status(priv, port, 1);
+ }
+-static void mt7530_phylink_validate(struct dsa_switch *ds, int port,
++static void mt753x_phylink_validate(struct dsa_switch *ds, int port,
+                                   unsigned long *supported,
+                                   struct phylink_link_state *state)
+ {
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+-      switch (port) {
+-      case 0: /* Internal phy */
+-      case 1:
+-      case 2:
+-      case 3:
+-      case 4:
+-              if (state->interface != PHY_INTERFACE_MODE_NA &&
+-                  state->interface != PHY_INTERFACE_MODE_GMII)
+-                      goto unsupported;
+-              break;
+-      case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
+-              if (state->interface != PHY_INTERFACE_MODE_NA &&
+-                  !phy_interface_mode_is_rgmii(state->interface) &&
+-                  state->interface != PHY_INTERFACE_MODE_MII &&
+-                  state->interface != PHY_INTERFACE_MODE_GMII)
+-                      goto unsupported;
+-              break;
+-      case 6: /* 1st cpu port */
+-              if (state->interface != PHY_INTERFACE_MODE_NA &&
+-                  state->interface != PHY_INTERFACE_MODE_RGMII &&
+-                  state->interface != PHY_INTERFACE_MODE_TRGMII)
+-                      goto unsupported;
+-              break;
+-      default:
+-              dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
+-unsupported:
++      if (state->interface != PHY_INTERFACE_MODE_NA &&
++          !mt753x_phy_supported(ds, port, state)) {
+               linkmode_zero(supported);
+               return;
+       }
+@@ -1609,12 +1674,36 @@ static int mt7530_set_mac_eee(struct dsa
+       return 0;
+ }
++static int
++mt753x_setup(struct dsa_switch *ds)
++{
++      struct mt7530_priv *priv = ds->priv;
++
++      return priv->info->setup(ds);
++}
++
++static int
++mt753x_phy_read(struct dsa_switch *ds, int port, int regnum)
++{
++      struct mt7530_priv *priv = ds->priv;
++
++      return priv->info->phy_read(ds, port, regnum);
++}
++
++static int
++mt753x_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
++{
++      struct mt7530_priv *priv = ds->priv;
++
++      return priv->info->phy_write(ds, port, regnum, val);
++}
++
+ static const struct dsa_switch_ops mt7530_switch_ops = {
+       .get_tag_protocol       = mtk_get_tag_protocol,
+-      .setup                  = mt7530_setup,
++      .setup                  = mt753x_setup,
+       .get_strings            = mt7530_get_strings,
+-      .phy_read               = mt7530_phy_read,
+-      .phy_write              = mt7530_phy_write,
++      .phy_read               = mt753x_phy_read,
++      .phy_write              = mt753x_phy_write,
+       .get_ethtool_stats      = mt7530_get_ethtool_stats,
+       .get_sset_count         = mt7530_get_sset_count,
+       .port_enable            = mt7530_port_enable,
+@@ -1631,18 +1720,39 @@ static const struct dsa_switch_ops mt753
+       .port_vlan_del          = mt7530_port_vlan_del,
+       .port_mirror_add        = mt7530_port_mirror_add,
+       .port_mirror_del        = mt7530_port_mirror_del,
+-      .phylink_validate       = mt7530_phylink_validate,
++      .phylink_validate       = mt753x_phylink_validate,
+       .phylink_mac_link_state = mt7530_phylink_mac_link_state,
+-      .phylink_mac_config     = mt7530_phylink_mac_config,
++      .phylink_mac_config     = mt753x_phylink_mac_config,
+       .phylink_mac_link_down  = mt7530_phylink_mac_link_down,
+       .phylink_mac_link_up    = mt7530_phylink_mac_link_up,
+       .get_mac_eee            = mt7530_get_mac_eee,
+       .set_mac_eee            = mt7530_set_mac_eee,
+ };
+-static const struct of_device_id mt7530_of_match[] = {
+-      { .compatible = "mediatek,mt7621", .data = (void *)ID_MT7621, },
+-      { .compatible = "mediatek,mt7530", .data = (void *)ID_MT7530, },
++static const struct mt753x_info mt753x_table[] = {
++      [ID_MT7621] = {
++              .id = ID_MT7621,
++              .setup = mt7530_setup,
++              .phy_read = mt7530_phy_read,
++              .phy_write = mt7530_phy_write,
++              .phy_supported = mt7530_phy_supported,
++              .pad_setup = mt7530_pad_setup,
++              .mac_setup = mt7530_mac_setup,
++      },
++      [ID_MT7530] = {
++              .id = ID_MT7530,
++              .setup = mt7530_setup,
++              .phy_read = mt7530_phy_read,
++              .phy_write = mt7530_phy_write,
++              .phy_supported = mt7530_phy_supported,
++              .pad_setup = mt7530_pad_setup,
++              .mac_setup = mt7530_mac_setup,
++      },
++};
++
++ static const struct of_device_id mt7530_of_match[] = {
++      { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
++      { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
+       { /* sentinel */ },
+ };
+ MODULE_DEVICE_TABLE(of, mt7530_of_match);
+@@ -1680,8 +1790,19 @@ mt7530_probe(struct mdio_device *mdiodev
+       /* Get the hardware identifier from the devicetree node.
+        * We will need it for some of the clock and regulator setup.
+        */
+-      priv->id = (unsigned int)(unsigned long)
+-              of_device_get_match_data(&mdiodev->dev);
++      priv->info = of_device_get_match_data(&mdiodev->dev);
++      if (!priv->info)
++              return -EINVAL;
++
++      /* Sanity check if these required device operstaions are filled
++       * properly.
++       */
++      if (!priv->info->setup || !priv->info->phy_read ||
++          !priv->info->phy_write || !priv->info->phy_supported ||
++          !priv->info->pad_setup || !priv->info->mac_setup)
++              return -EINVAL;
++
++      priv->id = priv->info->id;
+       if (priv->id == ID_MT7530) {
+               priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
+Index: linux-5.4.43/drivers/net/dsa/mt7530.h
+===================================================================
+--- linux-5.4.43.orig/drivers/net/dsa/mt7530.h
++++ linux-5.4.43/drivers/net/dsa/mt7530.h
+@@ -11,7 +11,7 @@
+ #define MT7530_NUM_FDB_RECORDS                2048
+ #define MT7530_ALL_MEMBERS            0xff
+-enum {
++enum mt753x_id {
+       ID_MT7530 = 0,
+       ID_MT7621 = 1,
+ };
+@@ -447,6 +447,32 @@ static const char *p5_intf_modes(unsigne
+       }
+ }
++/* struct mt753x_info -       This is the main data structure for holding the specific
++ *                    part for each supported device
++ * @setup:            Holding the handler to a device initialization
++ * @phy_read:         Holding the way reading PHY port
++ * @phy_write:                Holding the way writing PHY port
++ * @phy_supported:    Check if the PHY type is being supported on a certain
++ *                    port
++ * @pad_setup:                Holding the way setting up the bus pad for a certain MAC
++ *                    port
++ * @mac_setup:                Holding the way setting up the PHY attribute for a
++ *                    certain MAC port
++ */
++struct mt753x_info {
++      enum mt753x_id id;
++
++      int (*setup)(struct dsa_switch *ds);
++      int (*phy_read)(struct dsa_switch *ds, int port, int regnum);
++      int (*phy_write)(struct dsa_switch *ds, int port, int regnum, u16 val);
++      bool (*phy_supported)(struct dsa_switch *ds, int port,
++                            const struct phylink_link_state *state);
++      int (*pad_setup)(struct dsa_switch *ds,
++                       const struct phylink_link_state *state);
++      int (*mac_setup)(struct dsa_switch *ds, int port, unsigned int mode,
++                       const struct phylink_link_state *state);
++};
++
+ /* struct mt7530_priv -       This is the main data structure for holding the state
+  *                    of the driver
+  * @dev:              The device pointer
+@@ -472,6 +498,7 @@ struct mt7530_priv {
+       struct regulator        *core_pwr;
+       struct regulator        *io_pwr;
+       struct gpio_desc        *reset;
++      const struct mt753x_info *info;
+       unsigned int            id;
+       bool                    mcm;
+       phy_interface_t         p6_interface;
diff --git a/target/linux/mediatek/patches-5.4/0600-3-6-dt-bindings-net-dsa-add-new-MT7531-binding-to-support-MT7531.patch b/target/linux/mediatek/patches-5.4/0600-3-6-dt-bindings-net-dsa-add-new-MT7531-binding-to-support-MT7531.patch
new file mode 100644 (file)
index 0000000..3ca12b9
--- /dev/null
@@ -0,0 +1,181 @@
+From patchwork Tue Dec 10 08:14:39 2019
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Landen Chao <landen.chao@mediatek.com>
+X-Patchwork-Id: 1206955
+X-Patchwork-Delegate: davem@davemloft.net
+Return-Path: <netdev-owner@vger.kernel.org>
+X-Original-To: patchwork-incoming-netdev@ozlabs.org
+Delivered-To: patchwork-incoming-netdev@ozlabs.org
+Authentication-Results: ozlabs.org; spf=none (no SPF record)
+ smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67;
+ helo=vger.kernel.org;
+ envelope-from=netdev-owner@vger.kernel.org;
+ receiver=<UNKNOWN>)
+Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none)
+ header.from=mediatek.com
+Authentication-Results: ozlabs.org; dkim=pass (1024-bit key;
+ unprotected) header.d=mediatek.com header.i=@mediatek.com
+ header.b="SuczJHZp"; dkim-atps=neutral
+Received: from vger.kernel.org (vger.kernel.org [209.132.180.67])
+ by ozlabs.org (Postfix) with ESMTP id 47XCXj3BBNz9sPh
+ for <patchwork-incoming-netdev@ozlabs.org>;
+ Tue, 10 Dec 2019 19:15:01 +1100 (AEDT)
+Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
+ id S1727133AbfLJIPA (ORCPT
+ <rfc822;patchwork-incoming-netdev@ozlabs.org>);
+ Tue, 10 Dec 2019 03:15:00 -0500
+Received: from mailgw02.mediatek.com ([210.61.82.184]:45567 "EHLO
+ mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by
+ vger.kernel.org with ESMTP id S1727022AbfLJIO7 (ORCPT
+ <rfc822;netdev@vger.kernel.org>); Tue, 10 Dec 2019 03:14:59 -0500
+X-UUID: a1d9a42928d44d63b201d5ad84c05baa-20191210
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
+ d=mediatek.com; s=dk; 
+ h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From;
+ bh=KJqQ2m7z9H4vre+SZyxgKEGRWb9Edp5pJlYnepJNMyM=; 
+ b=SuczJHZpeY7vF8UsCGorYUAcT2lEUX2E0ciiyQBS1rDLPzTYnufK8OXyAw5Uq8U1m72TGWYCaq1o0VWtI1meJpEmCL2TVK/d+Y+IaacHlO716BmX77+0MU0crczE8zx1Nz2pNh+GicsB6AoC9qbBU+p5egbKDMBhpRaGQNAeBww=;
+X-UUID: a1d9a42928d44d63b201d5ad84c05baa-20191210
+Received: from mtkcas07.mediatek.inc [(172.21.101.84)] by
+ mailgw02.mediatek.com (envelope-from <landen.chao@mediatek.com>)
+ (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS)
+ with ESMTP id 297826603; Tue, 10 Dec 2019 16:14:47 +0800
+Received: from mtkcas08.mediatek.inc (172.21.101.126) by
+ mtkmbs07n1.mediatek.inc (172.21.101.16) with Microsoft SMTP Server
+ (TLS) id 15.0.1395.4; Tue, 10 Dec 2019 16:14:38 +0800
+Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas08.mediatek.inc
+ (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via
+ Frontend Transport; Tue, 10 Dec 2019 16:14:26 +0800
+From: Landen Chao <landen.chao@mediatek.com>
+To: <andrew@lunn.ch>, <f.fainelli@gmail.com>,
+ <vivien.didelot@savoirfairelinux.com>, <matthias.bgg@gmail.com>,
+ <robh+dt@kernel.org>, <mark.rutland@arm.com>
+CC: <devicetree@vger.kernel.org>, <netdev@vger.kernel.org>,
+ <linux-kernel@vger.kernel.org>,
+ <linux-mediatek@lists.infradead.org>, <davem@davemloft.net>,
+ <sean.wang@mediatek.com>, <opensource@vdorst.com>,
+ <frank-w@public-files.de>, Landen Chao <landen.chao@mediatek.com>
+Subject: [PATCH net-next 3/6] dt-bindings: net: dsa: add new MT7531 binding
+ to support MT7531
+Date: Tue, 10 Dec 2019 16:14:39 +0800
+Message-ID: <1c382fd916b66bfe3ce8ef18c12f954dbcbddbbc.1575914275.git.landen.chao@mediatek.com>
+X-Mailer: git-send-email 2.18.0
+In-Reply-To: <cover.1575914275.git.landen.chao@mediatek.com>
+References: <cover.1575914275.git.landen.chao@mediatek.com>
+MIME-Version: 1.0
+X-MTK: N
+Sender: netdev-owner@vger.kernel.org
+Precedence: bulk
+List-ID: <netdev.vger.kernel.org>
+X-Mailing-List: netdev@vger.kernel.org
+
+Add devicetree binding to support the compatible mt7531 switch as used
+in the MediaTek MT7531 switch.
+
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+Signed-off-by: Landen Chao <landen.chao@mediatek.com>
+---
+ .../devicetree/bindings/net/dsa/mt7530.txt    | 77 ++++++++++++++++++-
+ 1 file changed, 74 insertions(+), 3 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/net/dsa/mt7530.txt b/Documentation/devicetree/bindings/net/dsa/mt7530.txt\r
+index c5ed5d25f642..dc226a4e402a 100644\r
+--- a/Documentation/devicetree/bindings/net/dsa/mt7530.txt\r
++++ b/Documentation/devicetree/bindings/net/dsa/mt7530.txt\r
+@@ -5,6 +5,7 @@ Required properties:\r
\r
+ - compatible: may be compatible = "mediatek,mt7530"\r
+       or compatible = "mediatek,mt7621"\r
++      or compatible = "mediatek,mt7531"\r
+ - #address-cells: Must be 1.\r
+ - #size-cells: Must be 0.\r
+ - mediatek,mcm: Boolean; if defined, indicates that either MT7530 is the part\r
+@@ -32,10 +33,13 @@ Required properties for the child nodes within ports container:\r
\r
+ - reg: Port address described must be 6 for CPU port and from 0 to 5 for\r
+       user ports.\r
+-- phy-mode: String, must be either "trgmii" or "rgmii" for port labeled\r
+-       "cpu".\r
++- phy-mode: String, the follow value would be acceptable for port labeled "cpu"\r
++      If compatible mediatek,mt7530 or mediatek,mt7621 is set,\r
++      must be either "trgmii" or "rgmii"\r
++      If compatible mediatek,mt7531 is set,\r
++      must be either "sgmii", "1000base-x" or "2500base-x"\r
\r
+-Port 5 of the switch is muxed between:\r
++Port 5 of mt7530 and mt7621 switch is muxed between:\r
+ 1. GMAC5: GMAC5 can interface with another external MAC or PHY.\r
+ 2. PHY of port 0 or port 4: PHY interfaces with an external MAC like 2nd GMAC\r
+    of the SOC. Used in many setups where port 0/4 becomes the WAN port.\r
+@@ -308,3 +312,70 @@ Example 3: MT7621: Port 5 is connected to external PHY: Port 5 -> external PHY.\r
+               };\r
+       };\r
+ };\r
++\r
++Example 4:\r
++\r
++&eth {\r
++      gmac0: mac@0 {\r
++              compatible = "mediatek,eth-mac";\r
++              reg = <0>;\r
++              phy-mode = "2500base-x";\r
++\r
++              fixed-link {\r
++                      speed = <1000>;\r
++                      full-duplex;\r
++                      pause;\r
++              };\r
++      };\r
++\r
++      &mdio0 {\r
++              switch@0 {\r
++                      compatible = "mediatek,mt7531";\r
++                      reg = <0>;\r
++                      reset-gpios = <&pio 54 0>;\r
++\r
++                      ports {\r
++                              #address-cells = <1>;\r
++                              #size-cells = <0>;\r
++                              reg = <0>;\r
++\r
++                              port@0 {\r
++                                      reg = <0>;\r
++                                      label = "lan0";\r
++                              };\r
++\r
++                              port@1 {\r
++                                      reg = <1>;\r
++                                      label = "lan1";\r
++                              };\r
++\r
++                              port@2 {\r
++                                      reg = <2>;\r
++                                      label = "lan2";\r
++                              };\r
++\r
++                              port@3 {\r
++                                      reg = <3>;\r
++                                      label = "lan3";\r
++                              };\r
++\r
++                              port@4 {\r
++                                      reg = <4>;\r
++                                      label = "wan";\r
++                              };\r
++\r
++                              port@6 {\r
++                                      reg = <6>;\r
++                                      label = "cpu";\r
++                                      ethernet = <&gmac0>;\r
++                                      phy-mode = "2500base-x";\r
++\r
++                                      fixed-link {\r
++                                              speed = <1000>;\r
++                                              full-duplex;\r
++                                              pause;\r
++                                      };\r
++                              };\r
++                      };\r
++              };\r
++      };\r
diff --git a/target/linux/mediatek/patches-5.4/0600-4-6-net-dsa-mt7530-Add-the-support-of-MT7531-switch.patch b/target/linux/mediatek/patches-5.4/0600-4-6-net-dsa-mt7530-Add-the-support-of-MT7531-switch.patch
new file mode 100644 (file)
index 0000000..a93b802
--- /dev/null
@@ -0,0 +1,1102 @@
+From patchwork Tue Dec 10 08:14:40 2019
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Landen Chao <landen.chao@mediatek.com>
+X-Patchwork-Id: 1206959
+X-Patchwork-Delegate: davem@davemloft.net
+Return-Path: <netdev-owner@vger.kernel.org>
+X-Original-To: patchwork-incoming-netdev@ozlabs.org
+Delivered-To: patchwork-incoming-netdev@ozlabs.org
+Authentication-Results: ozlabs.org; spf=none (no SPF record)
+ smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67;
+ helo=vger.kernel.org;
+ envelope-from=netdev-owner@vger.kernel.org;
+ receiver=<UNKNOWN>)
+Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none)
+ header.from=mediatek.com
+Authentication-Results: ozlabs.org; dkim=pass (1024-bit key;
+ unprotected) header.d=mediatek.com header.i=@mediatek.com
+ header.b="A6fsNqWU"; dkim-atps=neutral
+Received: from vger.kernel.org (vger.kernel.org [209.132.180.67])
+ by ozlabs.org (Postfix) with ESMTP id 47XCXz2fDsz9sPh
+ for <patchwork-incoming-netdev@ozlabs.org>;
+ Tue, 10 Dec 2019 19:15:15 +1100 (AEDT)
+Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
+ id S1727198AbfLJIPC (ORCPT
+ <rfc822;patchwork-incoming-netdev@ozlabs.org>);
+ Tue, 10 Dec 2019 03:15:02 -0500
+Received: from mailgw02.mediatek.com ([210.61.82.184]:39119 "EHLO
+ mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by
+ vger.kernel.org with ESMTP id S1726750AbfLJIPC (ORCPT
+ <rfc822;netdev@vger.kernel.org>); Tue, 10 Dec 2019 03:15:02 -0500
+X-UUID: 38155314c18e497aacbec5bc0f664b9a-20191210
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
+ d=mediatek.com; s=dk; 
+ h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From;
+ bh=sEkoMPWKI3m+K/8A3kC0uuYTNxZZaGCvfLKvnEmwQQ4=; 
+ b=A6fsNqWUmjxIiZPLPb43Hs36qwwvYXMLQ/LlU24IcsfBro20uMkDbzGq522r69u0071Qgekwc/zs4yujo0pz40jCfnAo38JIDP73w4ZyVGuOENM5gdE+qNNUednOVSi052hcMRhS7zpVD0Rfl7vKKOU42F7Tl+cadVzjUl0ow/s=;
+X-UUID: 38155314c18e497aacbec5bc0f664b9a-20191210
+Received: from mtkcas09.mediatek.inc [(172.21.101.178)] by
+ mailgw02.mediatek.com (envelope-from <landen.chao@mediatek.com>)
+ (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS)
+ with ESMTP id 452927388; Tue, 10 Dec 2019 16:14:46 +0800
+Received: from mtkcas08.mediatek.inc (172.21.101.126) by
+ mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server
+ (TLS) id 15.0.1395.4; Tue, 10 Dec 2019 16:14:31 +0800
+Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas08.mediatek.inc
+ (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via
+ Frontend Transport; Tue, 10 Dec 2019 16:14:26 +0800
+From: Landen Chao <landen.chao@mediatek.com>
+To: <andrew@lunn.ch>, <f.fainelli@gmail.com>,
+ <vivien.didelot@savoirfairelinux.com>, <matthias.bgg@gmail.com>,
+ <robh+dt@kernel.org>, <mark.rutland@arm.com>
+CC: <devicetree@vger.kernel.org>, <netdev@vger.kernel.org>,
+ <linux-kernel@vger.kernel.org>,
+ <linux-mediatek@lists.infradead.org>, <davem@davemloft.net>,
+ <sean.wang@mediatek.com>, <opensource@vdorst.com>,
+ <frank-w@public-files.de>, Landen Chao <landen.chao@mediatek.com>
+Subject: [PATCH net-next 4/6] net: dsa: mt7530: Add the support of MT7531
+ switch
+Date: Tue, 10 Dec 2019 16:14:40 +0800
+Message-ID: <6d608dd024edc90b09ba4fe35417b693847f973c.1575914275.git.landen.chao@mediatek.com>
+X-Mailer: git-send-email 2.18.0
+In-Reply-To: <cover.1575914275.git.landen.chao@mediatek.com>
+References: <cover.1575914275.git.landen.chao@mediatek.com>
+MIME-Version: 1.0
+X-MTK: N
+Sender: netdev-owner@vger.kernel.org
+Precedence: bulk
+List-ID: <netdev.vger.kernel.org>
+X-Mailing-List: netdev@vger.kernel.org
+
+Add new support for MT7531:
+
+MT7531 is the next generation of MT7530. It is also a 7-ports switch with
+5 giga embedded phys, 2 cpu ports, and the same MAC logic of MT7530. Cpu
+port 6 only supports HSGMII interface. Cpu port 5 supports either RGMII
+or HSGMII in different HW sku. Due to HSGMII interface support, pll, and
+pad setting are different from MT7530. This patch adds different initial
+setting of MT7531.
+
+Signed-off-by: Landen Chao <landen.chao@mediatek.com>
+Signed-off-by: Sean Wang <sean.wang@mediatek.com>
+---
+ drivers/net/dsa/Kconfig  |   6 +-
+ drivers/net/dsa/mt7530.c | 643 ++++++++++++++++++++++++++++++++++++++-
+ drivers/net/dsa/mt7530.h | 144 +++++++++
+ 3 files changed, 784 insertions(+), 9 deletions(-)
+
+Index: linux-5.4.43/drivers/net/dsa/Kconfig
+===================================================================
+--- linux-5.4.43.orig/drivers/net/dsa/Kconfig
++++ linux-5.4.43/drivers/net/dsa/Kconfig
+@@ -33,12 +33,12 @@ config NET_DSA_LANTIQ_GSWIP
+         the xrx200 / VR9 SoC.
+ config NET_DSA_MT7530
+-      tristate "MediaTek MT7530 and MT7621 Ethernet switch support"
++      tristate "MediaTek MT753x and MT7621 Ethernet switch support"
+       depends on NET_DSA
+       select NET_DSA_TAG_MTK
+       ---help---
+-        This enables support for the MediaTek MT7530 and MT7621 Ethernet
+-        switch chip.
++        This enables support for the MediaTek MT7530, MT7531 and MT7621
++        Ethernet switch chip.
+ config NET_DSA_MV88E6060
+       tristate "Marvell 88E6060 ethernet switch chip support"
+Index: linux-5.4.43/drivers/net/dsa/mt7530.c
+===================================================================
+--- linux-5.4.43.orig/drivers/net/dsa/mt7530.c
++++ linux-5.4.43/drivers/net/dsa/mt7530.c
+@@ -234,6 +234,12 @@ mt7530_write(struct mt7530_priv *priv, u
+ }
+ static u32
++_mt7530_unlocked_read(struct mt7530_dummy_poll *p)
++{
++      return mt7530_mii_read(p->priv, p->reg);
++}
++
++static u32
+ _mt7530_read(struct mt7530_dummy_poll *p)
+ {
+       struct mii_bus          *bus = p->priv->bus;
+@@ -287,6 +293,102 @@ mt7530_clear(struct mt7530_priv *priv, u
+ }
+ static int
++mt7531_ind_mmd_phy_read(struct mt7530_priv *priv, int port, int devad,
++                      int regnum)
++{
++      struct mii_bus *bus = priv->bus;
++      struct mt7530_dummy_poll p;
++      u32 reg, val;
++      int ret;
++
++      INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
++
++      mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
++
++      ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
++                               !(val & PHY_ACS_ST), 20, 100000);
++      if (ret < 0) {
++              dev_err(priv->dev, "poll timeout\n");
++              goto out;
++      }
++
++      reg = MDIO_CL45_ADDR | MDIO_PHY_ADDR(port) | MDIO_DEV_ADDR(devad) |
++            regnum;
++      mt7530_mii_write(priv, MT7531_PHY_IAC, reg | PHY_ACS_ST);
++
++      ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
++                               !(val & PHY_ACS_ST), 20, 100000);
++      if (ret < 0) {
++              dev_err(priv->dev, "poll timeout\n");
++              goto out;
++      }
++
++      reg = MDIO_CL45_READ | MDIO_PHY_ADDR(port) | MDIO_DEV_ADDR(devad);
++      mt7530_mii_write(priv, MT7531_PHY_IAC, reg | PHY_ACS_ST);
++
++      ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
++                               !(val & PHY_ACS_ST), 20, 100000);
++      if (ret < 0) {
++              dev_err(priv->dev, "poll timeout\n");
++              goto out;
++      }
++
++      ret = val & MDIO_RW_DATA_MASK;
++out:
++      mutex_unlock(&bus->mdio_lock);
++
++      return ret;
++}
++
++static int
++mt7531_ind_mmd_phy_write(struct mt7530_priv *priv, int port, int devad,
++                       int regnum, u32 data)
++{
++      struct mii_bus *bus = priv->bus;
++      struct mt7530_dummy_poll p;
++      u32 val, reg;
++      int ret;
++
++      INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
++
++      mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
++
++      ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
++                               !(val & PHY_ACS_ST), 20, 100000);
++      if (ret < 0) {
++              dev_err(priv->dev, "poll timeout\n");
++              goto out;
++      }
++
++      reg = MDIO_CL45_ADDR | MDIO_PHY_ADDR(port) | MDIO_DEV_ADDR(devad) |
++            regnum;
++      mt7530_mii_write(priv, MT7531_PHY_IAC, reg | PHY_ACS_ST);
++
++      ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
++                               !(val & PHY_ACS_ST), 20, 100000);
++      if (ret < 0) {
++              dev_err(priv->dev, "poll timeout\n");
++              goto out;
++      }
++
++      reg = MDIO_CL45_WRITE | MDIO_PHY_ADDR(port) | MDIO_DEV_ADDR(devad) |
++            data;
++      mt7530_mii_write(priv, MT7531_PHY_IAC, reg | PHY_ACS_ST);
++
++      ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
++                               !(val & PHY_ACS_ST), 20, 100000);
++      if (ret < 0) {
++              dev_err(priv->dev, "poll timeout\n");
++              goto out;
++      }
++
++out:
++      mutex_unlock(&bus->mdio_lock);
++
++      return ret;
++}
++
++static int
+ mt7530_fdb_cmd(struct mt7530_priv *priv, enum mt7530_fdb_cmd cmd, u32 *rsp)
+ {
+       u32 val;
+@@ -516,6 +618,83 @@ static int mt7530_phy_write(struct dsa_s
+       return mdiobus_write_nested(priv->bus, port, regnum, val);
+ }
++static int
++mt7531_ind_phy_read(struct dsa_switch *ds, int port, int regnum)
++{
++      struct mt7530_priv *priv = ds->priv;
++      struct mii_bus *bus = priv->bus;
++      struct mt7530_dummy_poll p;
++      int ret;
++      u32 val;
++
++      INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
++
++      mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
++
++      ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
++                               !(val & PHY_ACS_ST), 20, 100000);
++      if (ret < 0) {
++              dev_err(priv->dev, "poll timeout\n");
++              goto out;
++      }
++
++      val = MDIO_CL22_READ | MDIO_PHY_ADDR(port) | MDIO_REG_ADDR(regnum);
++
++      mt7530_mii_write(priv, MT7531_PHY_IAC, val | PHY_ACS_ST);
++
++      ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
++                               !(val & PHY_ACS_ST), 20, 100000);
++      if (ret < 0) {
++              dev_err(priv->dev, "poll timeout\n");
++              goto out;
++      }
++
++      ret = val & MDIO_RW_DATA_MASK;
++out:
++      mutex_unlock(&bus->mdio_lock);
++
++      return ret;
++}
++
++static int
++mt7531_ind_phy_write(struct dsa_switch *ds, int port, int regnum,
++                   u16 data)
++{
++      struct mt7530_priv *priv = ds->priv;
++      struct mii_bus *bus = priv->bus;
++      struct mt7530_dummy_poll p;
++      int ret;
++      u32 reg;
++
++      INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
++
++      mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
++
++      ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
++                               !(reg & PHY_ACS_ST), 20, 100000);
++      if (ret < 0) {
++              dev_err(priv->dev, "poll timeout\n");
++              goto out;
++      }
++
++      reg = MDIO_CL22_WRITE | MDIO_PHY_ADDR(port) | MDIO_REG_ADDR(regnum) |
++            data;
++
++      mt7530_mii_write(priv, MT7531_PHY_IAC, reg | PHY_ACS_ST);
++
++      ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
++                               !(reg & PHY_ACS_ST), 20, 100000);
++      if (ret < 0) {
++              dev_err(priv->dev, "poll timeout\n");
++              goto out;
++      }
++
++out:
++      mutex_unlock(&bus->mdio_lock);
++
++      return ret;
++}
++
+ static void
+ mt7530_get_strings(struct dsa_switch *ds, int port, u32 stringset,
+                  uint8_t *data)
+@@ -1355,6 +1534,86 @@ mt7530_setup(struct dsa_switch *ds)
+       return 0;
+ }
++static int mt7531_setup(struct dsa_switch *ds)
++{
++      struct mt7530_priv *priv = ds->priv;
++      struct mt7530_dummy_poll p;
++      u32 val, id;
++      int ret, i;
++
++      /* Reset whole chip through gpio pin or memory-mapped registers for
++       * different type of hardware
++       */
++      if (priv->mcm) {
++              reset_control_assert(priv->rstc);
++              usleep_range(1000, 1100);
++              reset_control_deassert(priv->rstc);
++      } else {
++              gpiod_set_value_cansleep(priv->reset, 0);
++              usleep_range(1000, 1100);
++              gpiod_set_value_cansleep(priv->reset, 1);
++      }
++
++      /* Waiting for MT7530 got to stable */
++      INIT_MT7530_DUMMY_POLL(&p, priv, MT7530_HWTRAP);
++      ret = readx_poll_timeout(_mt7530_read, &p, val, val != 0,
++                               20, 1000000);
++      if (ret < 0) {
++              dev_err(priv->dev, "reset timeout\n");
++              return ret;
++      }
++
++      id = mt7530_read(priv, MT7531_CREV);
++      id >>= CHIP_NAME_SHIFT;
++
++      if (id != MT7531_ID) {
++              dev_err(priv->dev, "chip %x can't be supported\n", id);
++              return -ENODEV;
++      }
++
++      /* Reset the switch through internal reset */
++      mt7530_write(priv, MT7530_SYS_CTRL,
++                   SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
++                   SYS_CTRL_REG_RST);
++
++      priv->p6_interface = PHY_INTERFACE_MODE_NA;
++
++      /* Enable PHY power, since phy_device has not yet been created
++       * provided for phy_[read,write]_mmd_indirect is called, we provide
++       * our own mt7531_ind_mmd_phy_[read,write] to complete this
++       * function.
++       */
++      val = mt7531_ind_mmd_phy_read(priv, 0, PHY_DEV1F,
++                                    MT7531_PHY_DEV1F_REG_403);
++      val |= MT7531_PHY_EN_BYPASS_MODE;
++      val &= ~MT7531_PHY_POWER_OFF;
++      mt7531_ind_mmd_phy_write(priv, 0, PHY_DEV1F,
++                               MT7531_PHY_DEV1F_REG_403, val);
++
++      /* Enable and reset MIB counters */
++      mt7530_mib_reset(ds);
++
++      mt7530_clear(priv, MT7530_MFC, UNU_FFP_MASK);
++
++      for (i = 0; i < MT7530_NUM_PORTS; i++) {
++              /* Disable forwarding by default on all ports */
++              mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
++                         PCR_MATRIX_CLR);
++
++              if (dsa_is_cpu_port(ds, i))
++                      mt7530_cpu_port_enable(priv, i);
++              else
++                      mt7530_port_disable(ds, i);
++      }
++
++      /* Flush the FDB table */
++      ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL);
++      if (ret < 0)
++              return ret;
++
++      return 0;
++}
++
+ static bool mt7530_phy_supported(struct dsa_switch *ds, int port,
+                                const struct phylink_link_state *state)
+ {
+@@ -1392,6 +1651,49 @@ unsupported:
+       return false;
+ }
++static bool mt7531_dual_sgmii_supported(struct mt7530_priv *priv)
++{
++      u32 val;
++
++      val = mt7530_read(priv, MT7531_TOP_SIG_SR);
++      return ((val & PAD_DUAL_SGMII_EN) != 0);
++}
++
++static bool mt7531_phy_supported(struct dsa_switch *ds, int port,
++                               const struct phylink_link_state *state)
++{
++      struct mt7530_priv *priv = ds->priv;
++
++      switch (port) {
++      case 0: /* Internal phy */
++      case 1:
++      case 2:
++      case 3:
++      case 4:
++              if (state->interface != PHY_INTERFACE_MODE_GMII)
++                      goto unsupported;
++              break;
++      case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */
++              if (!mt7531_dual_sgmii_supported(priv))
++                      return phy_interface_mode_is_rgmii(state->interface);
++              /* fall through */
++      case 6: /* 1st cpu port supports sgmii/8023z only */
++              if (state->interface != PHY_INTERFACE_MODE_SGMII &&
++                  !phy_interface_mode_is_8023z(state->interface))
++                      goto unsupported;
++              break;
++      default:
++              dev_err(priv->dev, "%s: unsupported port: %i\n", __func__,
++                      port);
++              goto unsupported;
++      }
++
++      return true;
++
++unsupported:
++      return false;
++}
++
+ static bool mt753x_phy_supported(struct dsa_switch *ds, int port,
+                                const struct phylink_link_state *state)
+ {
+@@ -1413,7 +1715,144 @@ mt7530_pad_setup(struct dsa_switch *ds,
+                * host which must be placed after the setup on the
+                * device side is all finished.
+                */
+-              mt7623_pad_clk_setup(ds);
++              //mt7623_pad_clk_setup(ds);
++      }
++
++      return 0;
++}
++
++static int
++mt7531_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
++{
++      struct mt7530_priv *priv = ds->priv;
++      u32 xtal, val;
++
++      if (mt7531_dual_sgmii_supported(priv))
++              return 0;
++
++      xtal = mt7530_read(priv, MT7531_HWTRAP) & HWTRAP_XTAL_FSEL_MASK;
++
++      switch (xtal) {
++      case HWTRAP_XTAL_FSEL_25MHZ:
++              /* Step 1 : Disable MT7531 COREPLL */
++              val = mt7530_read(priv, MT7531_PLLGP_EN);
++              val &= ~EN_COREPLL;
++              mt7530_write(priv, MT7531_PLLGP_EN, val);
++
++              /* Step 2: switch to XTAL output */
++              val = mt7530_read(priv, MT7531_PLLGP_EN);
++              val |= SW_CLKSW;
++              mt7530_write(priv, MT7531_PLLGP_EN, val);
++
++              val = mt7530_read(priv, MT7531_PLLGP_CR0);
++              val &= ~RG_COREPLL_EN;
++              mt7530_write(priv, MT7531_PLLGP_CR0, val);
++
++              /* Step 3: disable PLLGP and enable program PLLGP */
++              val = mt7530_read(priv, MT7531_PLLGP_EN);
++              val |= SW_PLLGP;
++              mt7530_write(priv, MT7531_PLLGP_EN, val);
++
++              /* Step 4: program COREPLL output frequency to 500MHz */
++              val = mt7530_read(priv, MT7531_PLLGP_CR0);
++              val &= ~RG_COREPLL_POSDIV_M;
++              val |= 2 << RG_COREPLL_POSDIV_S;
++              mt7530_write(priv, MT7531_PLLGP_CR0, val);
++              usleep_range(25, 35);
++
++              val = mt7530_read(priv, MT7531_PLLGP_CR0);
++              val &= ~RG_COREPLL_SDM_PCW_M;
++              val |= 0x140000 << RG_COREPLL_SDM_PCW_S;
++              mt7530_write(priv, MT7531_PLLGP_CR0, val);
++
++              /* Set feedback divide ratio update signal to high */
++              val = mt7530_read(priv, MT7531_PLLGP_CR0);
++              val |= RG_COREPLL_SDM_PCW_CHG;
++              mt7530_write(priv, MT7531_PLLGP_CR0, val);
++              /* Wait for at least 16 XTAL clocks */
++              usleep_range(10, 20);
++
++              /* Step 5: set feedback divide ratio update signal to low */
++              val = mt7530_read(priv, MT7531_PLLGP_CR0);
++              val &= ~RG_COREPLL_SDM_PCW_CHG;
++              mt7530_write(priv, MT7531_PLLGP_CR0, val);
++
++              /* Enable 325M clock for SGMII */
++              mt7530_write(priv, MT7531_ANA_PLLGP_CR5, 0xad0000);
++
++              /* Enable 250SSC clock for RGMII */
++              mt7530_write(priv, MT7531_ANA_PLLGP_CR2, 0x4f40000);
++
++              /* Step 6: Enable MT7531 PLL */
++              val = mt7530_read(priv, MT7531_PLLGP_CR0);
++              val |= RG_COREPLL_EN;
++              mt7530_write(priv, MT7531_PLLGP_CR0, val);
++
++              val = mt7530_read(priv, MT7531_PLLGP_EN);
++              val |= EN_COREPLL;
++              mt7530_write(priv, MT7531_PLLGP_EN, val);
++              usleep_range(25, 35);
++              break;
++      case HWTRAP_XTAL_FSEL_40MHZ:
++              /* Step 1 : Disable MT7531 COREPLL */
++              val = mt7530_read(priv, MT7531_PLLGP_EN);
++              val &= ~EN_COREPLL;
++              mt7530_write(priv, MT7531_PLLGP_EN, val);
++
++              /* Step 2: switch to XTAL output */
++              val = mt7530_read(priv, MT7531_PLLGP_EN);
++              val |= SW_CLKSW;
++              mt7530_write(priv, MT7531_PLLGP_EN, val);
++
++              val = mt7530_read(priv, MT7531_PLLGP_CR0);
++              val &= ~RG_COREPLL_EN;
++              mt7530_write(priv, MT7531_PLLGP_CR0, val);
++
++              /* Step 3: disable PLLGP and enable program PLLGP */
++              val = mt7530_read(priv, MT7531_PLLGP_EN);
++              val |= SW_PLLGP;
++              mt7530_write(priv, MT7531_PLLGP_EN, val);
++
++              /* Step 4: program COREPLL output frequency to 500MHz */
++              val = mt7530_read(priv, MT7531_PLLGP_CR0);
++              val &= ~RG_COREPLL_POSDIV_M;
++              val |= 2 << RG_COREPLL_POSDIV_S;
++              mt7530_write(priv, MT7531_PLLGP_CR0, val);
++              usleep_range(25, 35);
++
++              val = mt7530_read(priv, MT7531_PLLGP_CR0);
++              val &= ~RG_COREPLL_SDM_PCW_M;
++              val |= 0x190000 << RG_COREPLL_SDM_PCW_S;
++              mt7530_write(priv, MT7531_PLLGP_CR0, val);
++
++              /* Set feedback divide ratio update signal to high */
++              val = mt7530_read(priv, MT7531_PLLGP_CR0);
++              val |= RG_COREPLL_SDM_PCW_CHG;
++              mt7530_write(priv, MT7531_PLLGP_CR0, val);
++              /* Wait for at least 16 XTAL clocks */
++              usleep_range(10, 20);
++
++              /* Step 5: set feedback divide ratio update signal to low */
++              val = mt7530_read(priv, MT7531_PLLGP_CR0);
++              val &= ~RG_COREPLL_SDM_PCW_CHG;
++              mt7530_write(priv, MT7531_PLLGP_CR0, val);
++
++              /* Enable 325M clock for SGMII */
++              mt7530_write(priv, MT7531_ANA_PLLGP_CR5, 0xad0000);
++
++              /* Enable 250SSC clock for RGMII */
++              mt7530_write(priv, MT7531_ANA_PLLGP_CR2, 0x4f40000);
++
++              /* Step 6: Enable MT7531 PLL */
++              val = mt7530_read(priv, MT7531_PLLGP_CR0);
++              val |= RG_COREPLL_EN;
++              mt7530_write(priv, MT7531_PLLGP_CR0, val);
++
++              val = mt7530_read(priv, MT7531_PLLGP_EN);
++              val |= EN_COREPLL;
++              mt7530_write(priv, MT7531_PLLGP_EN, val);
++              usleep_range(25, 35);
++              break;
+       }
+       return 0;
+@@ -1442,6 +1881,149 @@ mt7530_mac_setup(struct dsa_switch *ds,
+       return 0;
+ }
++static int mt7531_rgmii_setup(struct mt7530_priv *priv, u32 port)
++{
++      u32 val;
++
++      if (port != 5) {
++              dev_err(priv->dev, "RGMII mode is not available for port %d\n",
++                      port);
++              return -EINVAL;
++      }
++
++      val = mt7530_read(priv, MT7531_CLKGEN_CTRL);
++      val |= GP_CLK_EN;
++      val &= ~GP_MODE_MASK;
++      val |= GP_MODE(MT7531_GP_MODE_RGMII);
++      val |= TXCLK_NO_REVERSE;
++      val |= RXCLK_NO_DELAY;
++      val &= ~CLK_SKEW_IN_MASK;
++      val |= CLK_SKEW_IN(MT7531_CLK_SKEW_NO_CHG);
++      val &= ~CLK_SKEW_OUT_MASK;
++      val |= CLK_SKEW_OUT(MT7531_CLK_SKEW_NO_CHG);
++      mt7530_write(priv, MT7531_CLKGEN_CTRL, val);
++
++      return 0;
++}
++
++static int mt7531_sgmii_setup_mode_force(struct mt7530_priv *priv, u32 port,
++                                       const struct phylink_link_state *state)
++{
++      u32 val;
++
++      if (port != 5 && port != 6)
++              return -EINVAL;
++
++      val = mt7530_read(priv, MT7531_QPHY_PWR_STATE_CTRL(port));
++      val |= MT7531_SGMII_PHYA_PWD;
++      mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), val);
++
++      val = mt7530_read(priv, MT7531_PHYA_CTRL_SIGNAL3(port));
++      val &= ~MT7531_RG_TPHY_SPEED_MASK;
++      if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
++              val |= MT7531_RG_TPHY_SPEED_3_125G;
++      mt7530_write(priv, MT7531_PHYA_CTRL_SIGNAL3(port), val);
++
++      val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
++      val &= ~MT7531_SGMII_AN_ENABLE;
++      mt7530_write(priv, MT7531_PCS_CONTROL_1(port), val);
++
++      val = mt7530_read(priv, MT7531_SGMII_MODE(port));
++      val &= ~MT7531_SGMII_IF_MODE_MASK;
++
++      switch (state->speed) {
++      case SPEED_10:
++              val |= MT7531_SGMII_FORCE_SPEED_10;
++              break;
++      case SPEED_100:
++              val |= MT7531_SGMII_FORCE_SPEED_100;
++              break;
++      case SPEED_2500:
++      case SPEED_1000:
++              val |= MT7531_SGMII_FORCE_SPEED_1000;
++              break;
++      };
++
++      val &= ~MT7531_SGMII_FORCE_DUPLEX;
++      /* For sgmii force mode, 0 is full duplex and 1 is half duplex */
++      if (state->duplex == DUPLEX_HALF)
++              val |= MT7531_SGMII_FORCE_DUPLEX;
++
++      mt7530_write(priv, MT7531_SGMII_MODE(port), val);
++
++      val = mt7530_read(priv, MT7531_QPHY_PWR_STATE_CTRL(port));
++      val &= ~MT7531_SGMII_PHYA_PWD;
++      mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), val);
++
++      return 0;
++}
++
++static int mt7531_sgmii_setup_mode_an(struct mt7530_priv *priv, int port,
++                                    const struct phylink_link_state *state)
++{
++      u32 val;
++
++      if (port != 5 && port != 6)
++              return -EINVAL;
++
++      val = mt7530_read(priv, MT7531_QPHY_PWR_STATE_CTRL(port));
++      val |= MT7531_SGMII_PHYA_PWD;
++      mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), val);
++
++      switch (state->speed) {
++      case SPEED_10:
++      case SPEED_100:
++      case SPEED_1000:
++              val = mt7530_read(priv, MT7531_PHYA_CTRL_SIGNAL3(port));
++              val &= ~MT7531_RG_TPHY_SPEED_MASK;
++              mt7530_write(priv, MT7531_PHYA_CTRL_SIGNAL3(port), val);
++              break;
++      default:
++              dev_info(priv->dev, "invalid SGMII speed idx %d for port %d\n",
++                       state->speed, port);
++
++              return -EINVAL;
++      }
++
++      val = mt7530_read(priv, MT7531_SGMII_MODE(port));
++      val |= MT7531_SGMII_REMOTE_FAULT_DIS;
++      mt7530_write(priv, MT7531_SGMII_MODE(port), val);
++
++      val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
++      val |= MT7531_SGMII_AN_RESTART;
++      mt7530_write(priv, MT7531_PCS_CONTROL_1(port), val);
++
++      val = mt7530_read(priv, MT7531_QPHY_PWR_STATE_CTRL(port));
++      val &= ~MT7531_SGMII_PHYA_PWD;
++      mt7530_write(priv, MT7531_QPHY_PWR_STATE_CTRL(port), val);
++
++      return 0;
++}
++
++static int
++mt7531_mac_setup(struct dsa_switch *ds, int port, unsigned int mode,
++               const struct phylink_link_state *state)
++{
++      struct mt7530_priv *priv = ds->priv;
++
++      if (port < 5 || port >= MT7530_NUM_PORTS) {
++              dev_err(priv->dev, "port %d is not a MAC port\n", port);
++              return -EINVAL;
++      }
++
++      switch (state->interface) {
++      case PHY_INTERFACE_MODE_RGMII:
++              return mt7531_rgmii_setup(priv, port);
++      case PHY_INTERFACE_MODE_1000BASEX:
++      case PHY_INTERFACE_MODE_2500BASEX:
++              return mt7531_sgmii_setup_mode_force(priv, port, state);
++      case PHY_INTERFACE_MODE_SGMII:
++              return mt7531_sgmii_setup_mode_an(priv, port, state);
++      default:
++              return -EINVAL;
++      }
++}
++
+ static int mt753x_mac_setup(struct dsa_switch *ds, int port, unsigned int mode,
+                           const struct phylink_link_state *state)
+ {
+@@ -1473,22 +2055,23 @@ static void mt753x_phylink_mac_config(st
+               if (priv->p5_interface == state->interface)
+                       break;
+               if (mt753x_mac_setup(ds, port, mode, state) < 0)
+-                      goto unsupported;
++                      break;
++              priv->p5_interface = state->interface;
+               break;
+       case 6: /* 1st cpu port */
+               if (priv->p6_interface == state->interface)
+                       break;
+               mt753x_pad_setup(ds, state);
+               if (mt753x_mac_setup(ds, port, mode, state) < 0)
+-                      goto unsupported;
++                      break;
+               priv->p6_interface = state->interface;
+               break;
+       default:
+-              dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
+               return;
+       }
+-      if (phylink_autoneg_inband(mode)) {
++      if (phylink_autoneg_inband(mode) &&
++          state->interface != PHY_INTERFACE_MODE_SGMII) {
+               dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
+                       __func__);
+               return;
+@@ -1499,13 +2082,15 @@ static void mt753x_phylink_mac_config(st
+       mcr_new &= ~(PMCR_FORCE_SPEED_1000 | PMCR_FORCE_SPEED_100 |
+                    PMCR_FORCE_FDX | PMCR_TX_FC_EN | PMCR_RX_FC_EN);
+       mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN |
+-                 PMCR_BACKPR_EN | PMCR_FORCE_MODE;
++                 PMCR_BACKPR_EN | PMCR_FORCE_MODE_ID(priv->id) |
++                 PMCR_FORCE_LNK;
+       /* Are we connected to external phy */
+       if (port == 5 && dsa_is_user_port(ds, 5))
+               mcr_new |= PMCR_EXT_PHY;
+       switch (state->speed) {
++      case SPEED_2500:
+       case SPEED_1000:
+               mcr_new |= PMCR_FORCE_SPEED_1000;
+               if (priv->eee_enable & BIT(port))
+@@ -1529,6 +2114,27 @@ static void mt753x_phylink_mac_config(st
+               mt7530_write(priv, MT7530_PMCR_P(port), mcr_new);
+ }
++void mt7531_sgmii_restart_an(struct dsa_switch *ds, int port)
++{
++      struct mt7530_priv *priv = ds->priv;
++      u32 val;
++
++      val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
++      val |= MT7531_SGMII_AN_RESTART;
++      mt7530_write(priv, MT7531_PCS_CONTROL_1(port), val);
++}
++
++static void
++mt753x_phylink_mac_an_restart(struct dsa_switch *ds, int port)
++{
++      struct mt7530_priv *priv = ds->priv;
++
++      if (!priv->info->port_an_restart)
++              return;
++
++      priv->info->port_an_restart(ds, port);
++}
++
+ static void mt7530_phylink_mac_link_down(struct dsa_switch *ds, int port,
+                                        unsigned int mode,
+                                        phy_interface_t interface)
+@@ -1563,9 +2169,20 @@ static void mt753x_phylink_validate(stru
+       phylink_set_port_modes(mask);
+       phylink_set(mask, Autoneg);
+-      if (state->interface == PHY_INTERFACE_MODE_TRGMII) {
++      switch (state->interface) {
++      case PHY_INTERFACE_MODE_TRGMII:
+               phylink_set(mask, 1000baseT_Full);
+-      } else {
++              break;
++      case PHY_INTERFACE_MODE_1000BASEX:
++      case PHY_INTERFACE_MODE_2500BASEX:
++              phylink_set(mask, 1000baseX_Full);
++              phylink_set(mask, 2500baseX_Full);
++              break;
++      case PHY_INTERFACE_MODE_SGMII:
++              phylink_set(mask, 1000baseT_Full);
++              phylink_set(mask, 1000baseX_Full);
++              /* fall through */
++      default:
+               phylink_set(mask, 10baseT_Half);
+               phylink_set(mask, 10baseT_Full);
+               phylink_set(mask, 100baseT_Half);
+@@ -1577,6 +2194,7 @@ static void mt753x_phylink_validate(stru
+                       if (port == 5)
+                               phylink_set(mask, 1000baseX_Full);
+               }
++              break;
+       }
+       phylink_set(mask, Pause);
+@@ -1721,8 +2339,9 @@ static const struct dsa_switch_ops mt753
+       .port_mirror_add        = mt7530_port_mirror_add,
+       .port_mirror_del        = mt7530_port_mirror_del,
+       .phylink_validate       = mt753x_phylink_validate,
+-      .phylink_mac_link_state = mt7530_phylink_mac_link_state,
++      .phylink_mac_link_state = mt7530_phylink_mac_link_state,
+       .phylink_mac_config     = mt753x_phylink_mac_config,
++      .phylink_mac_an_restart = mt753x_phylink_mac_an_restart,
+       .phylink_mac_link_down  = mt7530_phylink_mac_link_down,
+       .phylink_mac_link_up    = mt7530_phylink_mac_link_up,
+       .get_mac_eee            = mt7530_get_mac_eee,
+@@ -1748,11 +2367,22 @@ static const struct mt753x_info mt753x_t
+               .pad_setup = mt7530_pad_setup,
+               .mac_setup = mt7530_mac_setup,
+       },
++      [ID_MT7531] = {
++              .id = ID_MT7531,
++              .setup = mt7531_setup,
++              .phy_read = mt7531_ind_phy_read,
++              .phy_write = mt7531_ind_phy_write,
++              .phy_supported = mt7531_phy_supported,
++              .pad_setup = mt7531_pad_setup,
++              .mac_setup = mt7531_mac_setup,
++              .port_an_restart = mt7531_sgmii_restart_an,
++      },
+ };
+  static const struct of_device_id mt7530_of_match[] = {
+       { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
+       { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
++      { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
+       { /* sentinel */ },
+ };
+ MODULE_DEVICE_TABLE(of, mt7530_of_match);
+Index: linux-5.4.43/drivers/net/dsa/mt7530.h
+===================================================================
+--- linux-5.4.43.orig/drivers/net/dsa/mt7530.h
++++ linux-5.4.43/drivers/net/dsa/mt7530.h
+@@ -14,6 +14,7 @@
+ enum mt753x_id {
+       ID_MT7530 = 0,
+       ID_MT7621 = 1,
++      ID_MT7531 = 2,
+ };
+ #define       NUM_TRGMII_CTRL                 5
+@@ -222,6 +223,19 @@ enum mt7530_vlan_port_attr {
+ #define  PMCR_FORCE_LNK                       BIT(0)
+ #define  PMCR_SPEED_MASK              (PMCR_FORCE_SPEED_100 | \
+                                        PMCR_FORCE_SPEED_1000)
++#define  MT7531_FORCE_LNK             BIT(31)
++#define  MT7531_FORCE_SPD             BIT(30)
++#define  MT7531_FORCE_DPX             BIT(29)
++#define  MT7531_FORCE_RX_FC           BIT(28)
++#define  MT7531_FORCE_TX_FC           BIT(27)
++#define  MT7531_FORCE_MODE            (MT7531_FORCE_LNK | \
++                                       MT7531_FORCE_SPD | \
++                                       MT7531_FORCE_DPX | \
++                                       MT7531_FORCE_RX_FC | \
++                                       MT7531_FORCE_TX_FC)
++#define  PMCR_FORCE_MODE_ID(id)               (((id) == ID_MT7531) ? \
++                                       MT7531_FORCE_MODE : \
++                                       PMCR_FORCE_MODE)
+ #define MT7530_PMSR_P(x)              (0x3008 + (x) * 0x100)
+ #define  PMSR_EEE1G                   BIT(7)
+@@ -258,12 +272,111 @@ enum mt7530_vlan_port_attr {
+                                        CCR_RX_OCT_CNT_BAD | \
+                                        CCR_TX_OCT_CNT_GOOD | \
+                                        CCR_TX_OCT_CNT_BAD)
++
++/* SGMII registers */
++#define MT7531_SGMII_REG_BASE         0x5000
++#define MT7531_SGMII_REG(p, r)                (MT7531_SGMII_REG_BASE + \
++                                      ((p) - 5) * 0x1000 + (r))
++
++/* SGMII PCS_CONTROL_1 */
++#define MT7531_PCS_CONTROL_1(p)               MT7531_SGMII_REG(p, 0x00)
++#define  MT7531_SGMII_LINK_STATUS     BIT(18)
++#define  MT7531_SGMII_AN_ENABLE               BIT(12)
++#define  MT7531_SGMII_AN_RESTART      BIT(9)
++
++/* Fields of SGMII_MODE */
++#define MT7531_SGMII_MODE(p)          MT7531_SGMII_REG(p, 0x20)
++#define  MT7531_SGMII_REMOTE_FAULT_DIS        BIT(8)
++#define  MT7531_SGMII_FORCE_DUPLEX    BIT(4)
++#define  MT7531_SGMII_IF_MODE_MASK    GENMASK(5, 1)
++#define  MT7531_SGMII_FORCE_SPEED_10  0x0
++#define  MT7531_SGMII_FORCE_SPEED_100 BIT(2)
++#define  MT7531_SGMII_FORCE_SPEED_1000        BIT(3)
++
++/* Fields of QPHY_PWR_STATE_CTRL */
++#define MT7531_QPHY_PWR_STATE_CTRL(p) MT7531_SGMII_REG(p, 0xe8)
++#define  MT7531_SGMII_PHYA_PWD                BIT(4)
++
++/* Values of SGMII SPEED */
++#define MT7531_PHYA_CTRL_SIGNAL3(p)   MT7531_SGMII_REG(p, 0x128)
++#define  MT7531_RG_TPHY_SPEED_MASK    (BIT(2) | BIT(3))
++#define  MT7531_RG_TPHY_SPEED_1_25G   0x0
++#define  MT7531_RG_TPHY_SPEED_3_125G  BIT(2)
++
+ /* Register for system reset */
+ #define MT7530_SYS_CTRL                       0x7000
+ #define  SYS_CTRL_PHY_RST             BIT(2)
+ #define  SYS_CTRL_SW_RST              BIT(1)
+ #define  SYS_CTRL_REG_RST             BIT(0)
++/* Register for PHY Indirect Access Control */
++#define MT7531_PHY_IAC                        0x701C
++#define  PHY_ACS_ST                   BIT(31)
++#define  MDIO_REG_ADDR_MASK           (0x1f << 25)
++#define  MDIO_PHY_ADDR_MASK           (0x1f << 20)
++#define  MDIO_CMD_MASK                        (0x3 << 18)
++#define  MDIO_ST_MASK                 (0x3 << 16)
++#define  MDIO_RW_DATA_MASK            (0xffff)
++#define  MDIO_REG_ADDR(x)             (((x) & 0x1f) << 25)
++#define  MDIO_DEV_ADDR(x)             (((x) & 0x1f) << 25)
++#define  MDIO_PHY_ADDR(x)             (((x) & 0x1f) << 20)
++#define  MDIO_CMD(x)                  (((x) & 0x3) << 18)
++#define  MDIO_ST(x)                   (((x) & 0x3) << 16)
++
++enum mt7531_phy_iac_cmd {
++      MT7531_MDIO_ADDR = 0,
++      MT7531_MDIO_WRITE = 1,
++      MT7531_MDIO_READ = 2,
++      MT7531_MDIO_READ_CL45 = 3,
++};
++
++/* MDIO_ST: MDIO start field */
++enum mt7531_mdio_st {
++      MT7531_MDIO_ST_CL45 = 0,
++      MT7531_MDIO_ST_CL22 = 1,
++};
++
++#define  MDIO_CL22_READ                       (MDIO_ST(MT7531_MDIO_ST_CL22) | \
++                                       MDIO_CMD(MT7531_MDIO_READ))
++#define  MDIO_CL22_WRITE              (MDIO_ST(MT7531_MDIO_ST_CL22) | \
++                                       MDIO_CMD(MT7531_MDIO_WRITE))
++#define  MDIO_CL45_ADDR                       (MDIO_ST(MT7531_MDIO_ST_CL45) | \
++                                       MDIO_CMD(MT7531_MDIO_ADDR))
++#define  MDIO_CL45_READ                       (MDIO_ST(MT7531_MDIO_ST_CL45) | \
++                                       MDIO_CMD(MT7531_MDIO_READ))
++#define  MDIO_CL45_WRITE              (MDIO_ST(MT7531_MDIO_ST_CL45) | \
++                                       MDIO_CMD(MT7531_MDIO_WRITE))
++
++#define MT7531_CLKGEN_CTRL            0x7500
++#define  CLK_SKEW_OUT(x)              (((x) & 0x3) << 8)
++#define  CLK_SKEW_OUT_MASK            (0x3 << 8)
++#define  CLK_SKEW_IN(x)                       (((x) & 0x3) << 6)
++#define  CLK_SKEW_IN_MASK             (0x3 << 6)
++#define  RXCLK_NO_DELAY                       BIT(5)
++#define  TXCLK_NO_REVERSE             BIT(4)
++#define  GP_MODE(x)                   (((x) & 0x3) << 1)
++#define  GP_MODE_MASK                 (0x3 << 1)
++#define  GP_CLK_EN                    BIT(0)
++
++#define PHY_DEV1F                     0x1f
++#define MT7531_PHY_DEV1F_REG_403      0x403
++
++#define MT7531_PHY_EN_BYPASS_MODE     BIT(4)
++#define MT7531_PHY_POWER_OFF          BIT(5)
++
++enum mt7531_gp_mode {
++      MT7531_GP_MODE_RGMII = 0,
++      MT7531_GP_MODE_MII = 1,
++      MT7531_GP_MODE_REV_MII = 2
++};
++
++enum mt7531_clk_skew {
++      MT7531_CLK_SKEW_NO_CHG = 0,
++      MT7531_CLK_SKEW_DLY_100PPS = 1,
++      MT7531_CLK_SKEW_DLY_200PPS = 2,
++      MT7531_CLK_SKEW_REVERSE = 3,
++};
++
+ /* Register for hw trap status */
+ #define MT7530_HWTRAP                 0x7800
+ #define  HWTRAP_XTAL_MASK             (BIT(10) | BIT(9))
+@@ -271,6 +384,11 @@ enum mt7530_vlan_port_attr {
+ #define  HWTRAP_XTAL_40MHZ            (BIT(10))
+ #define  HWTRAP_XTAL_20MHZ            (BIT(9))
++#define MT7531_HWTRAP                 0x7800
++#define  HWTRAP_XTAL_FSEL_MASK                BIT(7)
++#define  HWTRAP_XTAL_FSEL_25MHZ               BIT(7)
++#define  HWTRAP_XTAL_FSEL_40MHZ               0
++
+ /* Register for hw trap modification */
+ #define MT7530_MHWTRAP                        0x7804
+ #define  MHWTRAP_PHY0_SEL             BIT(20)
+@@ -285,14 +403,34 @@ enum mt7530_vlan_port_attr {
+ #define MT7530_TOP_SIG_CTRL           0x7808
+ #define  TOP_SIG_CTRL_NORMAL          (BIT(17) | BIT(16))
++#define MT7531_TOP_SIG_SR             0x780c
++#define  PAD_DUAL_SGMII_EN            BIT(1)
++
+ #define MT7530_IO_DRV_CR              0x7810
+ #define  P5_IO_CLK_DRV(x)             ((x) & 0x3)
+ #define  P5_IO_DATA_DRV(x)            (((x) & 0x3) << 4)
++#define MT7531_PLLGP_EN                       0x7820
++#define  EN_COREPLL                   BIT(2)
++#define  SW_CLKSW                     BIT(1)
++#define  SW_PLLGP                     BIT(0)
++
++#define MT7531_PLLGP_CR0              0x78a8
++#define  RG_COREPLL_EN                        BIT(22)
++#define  RG_COREPLL_POSDIV_S          23
++#define  RG_COREPLL_POSDIV_M          0x3800000
++#define  RG_COREPLL_SDM_PCW_S         1
++#define  RG_COREPLL_SDM_PCW_M         0x3ffffe
++#define  RG_COREPLL_SDM_PCW_CHG               BIT(0)
++
+ #define MT7530_P6ECR                  0x7830
+ #define  P6_INTF_MODE_MASK            0x3
+ #define  P6_INTF_MODE(x)              ((x) & 0x3)
++/* RGMII and SGMII PLL clock */
++#define MT7531_ANA_PLLGP_CR2          0x78b0
++#define MT7531_ANA_PLLGP_CR5          0x78bc
++
+ /* Registers for TRGMII on the both side */
+ #define MT7530_TRGMII_RCK_CTRL                0x7a00
+ #define  RX_RST                               BIT(31)
+@@ -335,6 +473,9 @@ enum mt7530_vlan_port_attr {
+ #define  CHIP_NAME_SHIFT              16
+ #define  MT7530_ID                    0x7530
++#define MT7531_CREV                   0x781C
++#define  MT7531_ID                    0x7531
++
+ /* Registers for core PLL access through mmd indirect */
+ #define CORE_PLL_GROUP2                       0x401
+ #define  RG_SYSPLL_EN_NORMAL          BIT(15)
+@@ -458,6 +599,8 @@ static const char *p5_intf_modes(unsigne
+  *                    port
+  * @mac_setup:                Holding the way setting up the PHY attribute for a
+  *                    certain MAC port
++ * @port_an_restart   Holding the way restarting 802.3z BaseX autonegotiation
++ *                    for a certain MAC port
+  */
+ struct mt753x_info {
+       enum mt753x_id id;
+@@ -471,6 +614,7 @@ struct mt753x_info {
+                        const struct phylink_link_state *state);
+       int (*mac_setup)(struct dsa_switch *ds, int port, unsigned int mode,
+                        const struct phylink_link_state *state);
++      void (*port_an_restart)(struct dsa_switch *ds, int port);
+ };
+ /* struct mt7530_priv -       This is the main data structure for holding the state
diff --git a/target/linux/mediatek/patches-5.4/0600-6-6-arm64-dts-mt7622-add-mt7531-dsa-to-bananapi-bpi-r64-board.patch b/target/linux/mediatek/patches-5.4/0600-6-6-arm64-dts-mt7622-add-mt7531-dsa-to-bananapi-bpi-r64-board.patch
new file mode 100644 (file)
index 0000000..a4899ca
--- /dev/null
@@ -0,0 +1,140 @@
+From patchwork Tue Dec 10 08:14:42 2019
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Landen Chao <landen.chao@mediatek.com>
+X-Patchwork-Id: 1206964
+X-Patchwork-Delegate: davem@davemloft.net
+Return-Path: <netdev-owner@vger.kernel.org>
+X-Original-To: patchwork-incoming-netdev@ozlabs.org
+Delivered-To: patchwork-incoming-netdev@ozlabs.org
+Authentication-Results: ozlabs.org; spf=none (no SPF record)
+ smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67;
+ helo=vger.kernel.org;
+ envelope-from=netdev-owner@vger.kernel.org;
+ receiver=<UNKNOWN>)
+Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none)
+ header.from=mediatek.com
+Authentication-Results: ozlabs.org; dkim=pass (1024-bit key;
+ unprotected) header.d=mediatek.com header.i=@mediatek.com
+ header.b="eagJVm76"; dkim-atps=neutral
+Received: from vger.kernel.org (vger.kernel.org [209.132.180.67])
+ by ozlabs.org (Postfix) with ESMTP id 47XCYF2fNjz9sR7
+ for <patchwork-incoming-netdev@ozlabs.org>;
+ Tue, 10 Dec 2019 19:15:29 +1100 (AEDT)
+Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
+ id S1727295AbfLJIP0 (ORCPT
+ <rfc822;patchwork-incoming-netdev@ozlabs.org>);
+ Tue, 10 Dec 2019 03:15:26 -0500
+Received: from mailgw01.mediatek.com ([210.61.82.183]:21469 "EHLO
+ mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by
+ vger.kernel.org with ESMTP id S1726062AbfLJIO4 (ORCPT
+ <rfc822;netdev@vger.kernel.org>); Tue, 10 Dec 2019 03:14:56 -0500
+X-UUID: f9b456136baf42daba0957485d388010-20191210
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
+ d=mediatek.com; s=dk; 
+ h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From;
+ bh=BT+q/z4xoeKXCk+y25bvARvW/z0vRa1uB7kHqAjvpaw=; 
+ b=eagJVm76XNgnVVvxDHR4QtcIyynPPYY4k7twyvlRAQeSnsJbABh1afLK+LlxnJ0TM069F+hNNzWXq7ZGru/I+gYhmqZcYCt/SkEYgxdTb0VNE+DIW0hmNAOoJ0i23gobJ3xa7JVRfIfeZcbjwRJSuqwzLBRZBLIFzqSs71VZx1Y=;
+X-UUID: f9b456136baf42daba0957485d388010-20191210
+Received: from mtkcas07.mediatek.inc [(172.21.101.84)] by
+ mailgw01.mediatek.com (envelope-from <landen.chao@mediatek.com>)
+ (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS)
+ with ESMTP id 1831961689; Tue, 10 Dec 2019 16:14:48 +0800
+Received: from mtkcas08.mediatek.inc (172.21.101.126) by
+ mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server
+ (TLS) id 15.0.1395.4; Tue, 10 Dec 2019 16:14:32 +0800
+Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas08.mediatek.inc
+ (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via
+ Frontend Transport; Tue, 10 Dec 2019 16:14:27 +0800
+From: Landen Chao <landen.chao@mediatek.com>
+To: <andrew@lunn.ch>, <f.fainelli@gmail.com>,
+ <vivien.didelot@savoirfairelinux.com>, <matthias.bgg@gmail.com>,
+ <robh+dt@kernel.org>, <mark.rutland@arm.com>
+CC: <devicetree@vger.kernel.org>, <netdev@vger.kernel.org>,
+ <linux-kernel@vger.kernel.org>,
+ <linux-mediatek@lists.infradead.org>, <davem@davemloft.net>,
+ <sean.wang@mediatek.com>, <opensource@vdorst.com>,
+ <frank-w@public-files.de>, Landen Chao <landen.chao@mediatek.com>
+Subject: [PATCH net-next 6/6] arm64: dts: mt7622: add mt7531 dsa to
+ bananapi-bpi-r64 board
+Date: Tue, 10 Dec 2019 16:14:42 +0800
+Message-ID: <62eef5503c117f48d4b41e94fd28d75e123590b4.1575914275.git.landen.chao@mediatek.com>
+X-Mailer: git-send-email 2.18.0
+In-Reply-To: <cover.1575914275.git.landen.chao@mediatek.com>
+References: <cover.1575914275.git.landen.chao@mediatek.com>
+MIME-Version: 1.0
+X-MTK: N
+Sender: netdev-owner@vger.kernel.org
+Precedence: bulk
+List-ID: <netdev.vger.kernel.org>
+X-Mailing-List: netdev@vger.kernel.org
+
+Add mt7531 dsa to bananapi-bpi-r64 board for 5 giga Ethernet ports support.
+
+Signed-off-by: Landen Chao <landen.chao@mediatek.com>
+---
+ .../dts/mediatek/mt7622-bananapi-bpi-r64.dts  | 50 +++++++++++++++++++
+ 1 file changed, 50 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts\r
+index 83e10591e0e5..ffacefee8e2a 100644\r
+--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts\r
++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts\r
+@@ -143,6 +143,56 @@\r
+       mdio: mdio-bus {\r
+               #address-cells = <1>;\r
+               #size-cells = <0>;\r
++\r
++              switch@0 {\r
++                      compatible = "mediatek,mt7531";\r
++                      reg = <0>;\r
++                      reset-gpios = <&pio 54 0>;\r
++\r
++                      ports {\r
++                              #address-cells = <1>;\r
++                              #size-cells = <0>;\r
++\r
++                              port@0 {\r
++                                      reg = <0>;\r
++                                      label = "wan";\r
++                              };\r
++\r
++                              port@1 {\r
++                                      reg = <1>;\r
++                                      label = "lan0";\r
++                              };\r
++\r
++                              port@2 {\r
++                                      reg = <2>;\r
++                                      label = "lan1";\r
++                              };\r
++\r
++                              port@3 {\r
++                                      reg = <3>;\r
++                                      label = "lan2";\r
++                              };\r
++\r
++                              port@4 {\r
++                                      reg = <4>;\r
++                                      label = "lan3";\r
++                              };\r
++\r
++                              port@6 {\r
++                                      reg = <6>;\r
++                                      label = "cpu";\r
++                                      ethernet = <&gmac0>;\r
++                                      phy-mode = "2500base-x";\r
++\r
++                                      fixed-link {\r
++                                              speed = <2500>;\r
++                                              full-duplex;\r
++                                              pause;\r
++                                      };\r
++                              };\r
++                      };\r
++              };\r
++\r
+       };\r
+ };\r
\r