From ad39d06df7f6c6af6249c0f33358ae2d799ec4b4 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 4 Jun 2020 15:07:28 +0200 Subject: mediatek: add mt7531 DSA support Signed-off-by: John Crispin --- ...vice-data-ready-for-adding-a-new-hardware.patch | 445 +++++++++++++++++++++ 1 file changed, 445 insertions(+) create mode 100644 target/linux/mediatek/patches-5.4/0600-2-6-net-dsa-mt7530-Extend-device-data-ready-for-adding-a-new-hardware.patch (limited to 'target/linux/mediatek/patches-5.4/0600-2-6-net-dsa-mt7530-Extend-device-data-ready-for-adding-a-new-hardware.patch') 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 index 0000000000..637f9e3c58 --- /dev/null +++ b/target/linux/mediatek/patches-5.4/0600-2-6-net-dsa-mt7530-Extend-device-data-ready-for-adding-a-new-hardware.patch @@ -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 +X-Patchwork-Id: 1206963 +X-Patchwork-Delegate: davem@davemloft.net +Return-Path: +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=) +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 ; + Tue, 10 Dec 2019 19:15:25 +1100 (AEDT) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S1727003AbfLJIO4 (ORCPT + ); + 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 + ); 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 ) + (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 +To: , , + , , + , +CC: , , + , + , , + , , + , Landen Chao +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: +References: +MIME-Version: 1.0 +X-MTK: N +Sender: netdev-owner@vger.kernel.org +Precedence: bulk +List-ID: +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 +Signed-off-by: Sean Wang +--- + 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; -- cgit v1.2.3