From: g...@kernel.org [mailto:g...@kernel.org]
Sent: Sunday, January 20, 2019 11:12 PM
To: Sean Wang <sean.w...@mediatek.com>; bj...@mork.no; and...@lunn.ch;
vivien.dide...@savoirfairelinux.com; f.faine...@gmail.com; netdev@vger.kernel.org
Cc: r...@vdorst.com; j...@phrozen.org; n...@brown.name; Greg Ungerer
<g...@kernel.org>
Subject: [PATCHv3 2/3] net: dsa: mt7530: support the 7530 switch on the
Mediatek MT7621 SoC
From: Greg Ungerer <g...@kernel.org>
The MediaTek MT7621 SoC device contains a 7530 switch, and the existing linux
kernel 7530 DSA switch driver can be used with it.
The bulk of the changes required stem from the 7621 having different regulator
and pad setup. The existing setup of these in the 7530 driver appears to be
very specific to its implemtation in the Mediatek
7623 SoC. (Not entirely surprising given the 7623 is a quad core ARM based SoC,
and the 7621 is a dual core, dual thread MIPS based SoC).
Create a new devicetree type, "mediatek,mt7621", to support the 7530 switch in
the 7621 SoC. There appears to be no usable ID register to distinguish it from a 7530 in
other hardware at runtime. This is used to carry out the appropriate configuration and
setup.
Signed-off-by: Greg Ungerer <g...@kernel.org>
---
drivers/net/dsa/mt7530.c | 97 ++++++++++++++++++++++++----------------
drivers/net/dsa/mt7530.h | 9 ++++
2 files changed, 67 insertions(+), 39 deletions(-)
v1: initial patch
v2: use separate devicetree binding
v3: rebase onto 5.0-rc3
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c index
a8a2c728afba..350ce4c4fd52 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -621,17 +621,19 @@ static void mt7530_adjust_link(struct dsa_switch *ds, int
port,
struct mt7530_priv *priv = ds->priv;
if (phy_is_pseudo_fixed_link(phydev)) {
- dev_dbg(priv->dev, "phy-mode for master device = %x\n",
- phydev->interface);
-
- /* Setup TX circuit incluing relevant PAD and driving */
- mt7530_pad_clk_setup(ds, phydev->interface);
-
- /* 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);
+ if (priv->id == ID_MT7530) {
+ dev_dbg(priv->dev, "phy-mode for master device = %x\n",
+ phydev->interface);
+
+ /* Setup TX circuit incluing relevant PAD and driving */
+ mt7530_pad_clk_setup(ds, phydev->interface);
+
+ /* 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);
+ }
} else {
u16 lcl_adv = 0, rmt_adv = 0;
u8 flowctrl;
@@ -687,6 +689,10 @@ mt7530_cpu_port_enable(struct mt7530_priv *priv,
/* Unknown unicast frame fordwarding to the cpu port */
mt7530_set(priv, MT7530_MFC, UNU_FFP(BIT(port)));
+ /* Set CPU port number */
+ if (priv->id == ID_MT7621)
+ mt7530_rmw(priv, MT7530_MFC, CPU_MASK, CPU_EN | CPU_PORT(port));
+
/* CPU port gets connected to all user ports of
* the switch
*/
@@ -1219,24 +1225,27 @@ mt7530_setup(struct dsa_switch *ds)
* as two netdev instances.
*/
dn = ds->ports[MT7530_CPU_PORT].master->dev.of_node->parent;
- priv->ethernet = syscon_node_to_regmap(dn);
- if (IS_ERR(priv->ethernet))
- return PTR_ERR(priv->ethernet);
- regulator_set_voltage(priv->core_pwr, 1000000, 1000000);
- ret = regulator_enable(priv->core_pwr);
- if (ret < 0) {
- dev_err(priv->dev,
- "Failed to enable core power: %d\n", ret);
- return ret;
- }
+ if (priv->id == ID_MT7530) {
+ priv->ethernet = syscon_node_to_regmap(dn);
+ if (IS_ERR(priv->ethernet))
+ return PTR_ERR(priv->ethernet);
+
+ regulator_set_voltage(priv->core_pwr, 1000000, 1000000);
+ ret = regulator_enable(priv->core_pwr);
+ if (ret < 0) {
+ dev_err(priv->dev,
+ "Failed to enable core power: %d\n", ret);
+ return ret;
+ }
- regulator_set_voltage(priv->io_pwr, 3300000, 3300000);
- ret = regulator_enable(priv->io_pwr);
- if (ret < 0) {
- dev_err(priv->dev, "Failed to enable io pwr: %d\n",
- ret);
- return ret;
+ regulator_set_voltage(priv->io_pwr, 3300000, 3300000);
+ ret = regulator_enable(priv->io_pwr);
+ if (ret < 0) {
+ dev_err(priv->dev, "Failed to enable io pwr: %d\n",
+ ret);
+ return ret;
+ }
}
/* Reset whole chip through gpio pin or memory-mapped registers for @@ -1326,9 +1335,17 @@ static const struct dsa_switch_ops mt7530_switch_ops = {
.port_vlan_del = mt7530_port_vlan_del,
};
+static const struct of_device_id mt7530_of_match[] = {
+ { .compatible = "mediatek,mt7621", .data = (void *)ID_MT7621, },
+ { .compatible = "mediatek,mt7530", .data = (void *)ID_MT7530, },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mt7530_of_match);
+
static int
mt7530_probe(struct mdio_device *mdiodev) {
+ const struct of_device_id *of_id;
struct mt7530_priv *priv;
struct device_node *dn;
@@ -1356,13 +1373,21 @@ mt7530_probe(struct mdio_device *mdiodev)
}
}
- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
- if (IS_ERR(priv->core_pwr))
- return PTR_ERR(priv->core_pwr);
+ /* Get the hardware identifier from the devicetree node.
+ * We will need it for some of the clock and regulator setup.
+ */
+ of_id = of_match_node(mt7530_of_match, dn);
+ priv->id = (unsigned int)of_id->data;