diff mbox series

[PATCHv3,2/3] net: dsa: mt7530: support the 7530 switch on the Mediatek MT7621 SoC

Message ID 20190121071140.23089-3-gerg@kernel.org
State Changes Requested
Delegated to: David Miller
Headers show
Series : net: support MT7530 switch in the MT7621 SoC | expand

Commit Message

Greg Ungerer Jan. 21, 2019, 7:11 a.m. UTC
From: Greg Ungerer <gerg@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 <gerg@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

Comments

kernel test robot Jan. 21, 2019, 4:56 p.m. UTC | #1
Hi Greg,

I love your patch! Perhaps something to improve:

[auto build test WARNING on net/master]
[also build test WARNING on v5.0-rc2 next-20190116]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/gerg-kernel-org/net-ethernet-mediatek-support-MT7621-SoC-ethernet-hardware/20190121-223911
config: sparc64-allmodconfig (attached as .config)
compiler: sparc64-linux-gnu-gcc (Debian 8.2.0-11) 8.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=8.2.0 make.cross ARCH=sparc64 

All warnings (new ones prefixed by >>):

   drivers/net//dsa/mt7530.c: In function 'mt7530_probe':
>> drivers/net//dsa/mt7530.c:1380:13: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     priv->id = (unsigned int)of_id->data;
                ^

vim +1380 drivers/net//dsa/mt7530.c

  1344	
  1345	static int
  1346	mt7530_probe(struct mdio_device *mdiodev)
  1347	{
  1348		const struct of_device_id *of_id;
  1349		struct mt7530_priv *priv;
  1350		struct device_node *dn;
  1351	
  1352		dn = mdiodev->dev.of_node;
  1353	
  1354		priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
  1355		if (!priv)
  1356			return -ENOMEM;
  1357	
  1358		priv->ds = dsa_switch_alloc(&mdiodev->dev, DSA_MAX_PORTS);
  1359		if (!priv->ds)
  1360			return -ENOMEM;
  1361	
  1362		/* Use medatek,mcm property to distinguish hardware type that would
  1363		 * casues a little bit differences on power-on sequence.
  1364		 */
  1365		priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
  1366		if (priv->mcm) {
  1367			dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
  1368	
  1369			priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
  1370			if (IS_ERR(priv->rstc)) {
  1371				dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
  1372				return PTR_ERR(priv->rstc);
  1373			}
  1374		}
  1375	
  1376		/* Get the hardware identifier from the devicetree node.
  1377		 * We will need it for some of the clock and regulator setup.
  1378		 */
  1379		of_id = of_match_node(mt7530_of_match, dn);
> 1380		priv->id = (unsigned int)of_id->data;
  1381	
  1382		if (priv->id == ID_MT7530) {
  1383			priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
  1384			if (IS_ERR(priv->core_pwr))
  1385				return PTR_ERR(priv->core_pwr);
  1386	
  1387			priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
  1388			if (IS_ERR(priv->io_pwr))
  1389				return PTR_ERR(priv->io_pwr);
  1390		}
  1391	
  1392		/* Not MCM that indicates switch works as the remote standalone
  1393		 * integrated circuit so the GPIO pin would be used to complete
  1394		 * the reset, otherwise memory-mapped register accessing used
  1395		 * through syscon provides in the case of MCM.
  1396		 */
  1397		if (!priv->mcm) {
  1398			priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
  1399							      GPIOD_OUT_LOW);
  1400			if (IS_ERR(priv->reset)) {
  1401				dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
  1402				return PTR_ERR(priv->reset);
  1403			}
  1404		}
  1405	
  1406		priv->bus = mdiodev->bus;
  1407		priv->dev = &mdiodev->dev;
  1408		priv->ds->priv = priv;
  1409		priv->ds->ops = &mt7530_switch_ops;
  1410		mutex_init(&priv->reg_mutex);
  1411		dev_set_drvdata(&mdiodev->dev, priv);
  1412	
  1413		return dsa_register_switch(priv->ds);
  1414	}
  1415	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Andrew Lunn Jan. 21, 2019, 5:04 p.m. UTC | #2
On Mon, Jan 21, 2019 at 05:11:39PM +1000, gerg@kernel.org wrote:
> From: Greg Ungerer <gerg@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 <gerg@kernel.org>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew
Greg Ungerer Jan. 22, 2019, 1:28 a.m. UTC | #3
On 22/1/19 3:04 am, Andrew Lunn wrote:
> On Mon, Jan 21, 2019 at 05:11:39PM +1000, gerg@kernel.org wrote:
>> From: Greg Ungerer <gerg@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 <gerg@kernel.org>
> 
> Reviewed-by: Andrew Lunn <andrew@lunn.ch>

Thanks Andrew, I'll add those reviewed by tags.

Regards
Greg
diff mbox series

Patch

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;
 
-	priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
-	if (IS_ERR(priv->io_pwr))
-		return PTR_ERR(priv->io_pwr);
+	if (priv->id == ID_MT7530) {
+		priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
+		if (IS_ERR(priv->core_pwr))
+			return PTR_ERR(priv->core_pwr);
+
+		priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
+		if (IS_ERR(priv->io_pwr))
+			return PTR_ERR(priv->io_pwr);
+	}
 
 	/* Not MCM that indicates switch works as the remote standalone
 	 * integrated circuit so the GPIO pin would be used to complete
@@ -1408,12 +1433,6 @@  mt7530_remove(struct mdio_device *mdiodev)
 	mutex_destroy(&priv->reg_mutex);
 }
 
-static const struct of_device_id mt7530_of_match[] = {
-	{ .compatible = "mediatek,mt7530" },
-	{ /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, mt7530_of_match);
-
 static struct mdio_driver mt7530_mdio_driver = {
 	.probe  = mt7530_probe,
 	.remove = mt7530_remove,
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index d9b407a22a58..a95ed958df5b 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -19,6 +19,11 @@ 
 #define MT7530_NUM_FDB_RECORDS		2048
 #define MT7530_ALL_MEMBERS		0xff
 
+enum {
+	ID_MT7530 = 0,
+	ID_MT7621 = 1,
+};
+
 #define	NUM_TRGMII_CTRL			5
 
 #define TRGMII_BASE(x)			(0x10000 + (x))
@@ -36,6 +41,9 @@ 
 #define  UNM_FFP(x)			(((x) & 0xff) << 16)
 #define  UNU_FFP(x)			(((x) & 0xff) << 8)
 #define  UNU_FFP_MASK			UNU_FFP(~0)
+#define  CPU_EN				BIT(7)
+#define  CPU_PORT(x)			((x) << 4)
+#define  CPU_MASK			(0xf << 4)
 
 /* Registers for address table access */
 #define MT7530_ATA1			0x74
@@ -430,6 +438,7 @@  struct mt7530_priv {
 	struct regulator	*core_pwr;
 	struct regulator	*io_pwr;
 	struct gpio_desc	*reset;
+	unsigned int		id;
 	bool			mcm;
 
 	struct mt7530_port	ports[MT7530_NUM_PORTS];